1. 程式人生 > >十八 二分搜尋樹的三種遍歷方式

十八 二分搜尋樹的三種遍歷方式

三種遍歷方式:

package com.lt.datastructure.BST;

public class BST<E extends Comparable<E>> {
     
    private class Node{
        public E e;
        Node left,right;
        
        public Node(E e) {
            this.e = e;
            this.left = left;
            this.right = right;
        }
       
    }
    
    
private Node root; private int size; public BST(){ root = null; size = 0; } public int size() { return size; } public boolean isEmpty(){ return size==0; } /* * 二分搜尋樹新增元素 * 小於根結點,新增到左邊,大於則新增到右邊,等於根節點,則不作任何改變,二分搜尋樹不包含重複元素 *
*/ public void add(E e){ //如果根節點為空 if(root == null){ root = new Node(e); size ++; }else{ add(root,e); } } //向以root為根的二分搜尋樹中插入元素E,遞迴演算法 private Node add(Node node , E e){ //遞迴的出口,找到子樹為null,則必然新增,完成操作 if
(node == null){ size++; return new Node(e); } if(e.compareTo(node.e)<0){ //如果左子樹為null,則node.left = new Node(e);如果不為空,繼續遞迴 node.left = add(node.left,e); } else if(e.compareTo(node.e)>0){ ////如果右子樹為null,則node.right = new Node(e);如果不為空,繼續遞迴 node.right = add(node.right,e); } //其他情況,比如元素相等,則返回傳進來的根節點,不做操作 return node; } //查詢二分搜尋樹中是否包含元素e public boolean contains(E e){ return contains(root,e); } //看以node為根的二分搜尋樹中是否含有元素e,遞迴實現 private boolean contains(Node node , E e){ if(node == null){ return false; } if(e.compareTo(node.e)==0){ return true; } else if(e.compareTo(node.e)<0){ return contains(node.left,e); }else{ return contains(node.right,e); } } /* * 二分搜尋樹的前序遍歷(先訪問結點,再訪問左,右子樹),最自然,最常用的遍歷方式 * * */ public void preOrder(){ preOrder(root); } private void preOrder(Node node){ //遞迴終止 if(node==null){ return; } //遞迴呼叫 System.out.println(node.e);//首先列印根節點 preOrder(node.left);//然後遞迴left,直到left為空,回溯,列印left由深到淺 preOrder(node.right);//最後遞迴完了left,遞迴right,right列印由淺到深 } //遍歷的展示 @Override public String toString() { StringBuilder res = new StringBuilder(); BSTString(root,0,res); return res.toString(); } //生成以node為根節點,深度為depth描述的字串 private void BSTString(Node node, int depth, StringBuilder res) { if(node==null){ res.append(DepthString(depth)+"null\n"); return; } res.append(DepthString(depth)+node.e+"\n"); BSTString(node.left,depth+1,res); BSTString(node.right, depth+1, res); } private String DepthString(int depth) { StringBuilder res = new StringBuilder(); for(int i=0; i<depth ; i++){ res.append("--"); } return res.toString(); } /* * 二分搜尋樹的中序遍歷(訪問左子樹,結點,右子樹),順序由小到大,最自然,最常用的遍歷方式 * */ public void inOrder(){ inOrder(root); } //中序遍歷以node為根的二分搜尋樹,遞迴演算法 private void inOrder(Node node){ if(node==null){ return; } inOrder(node.left);//由深到淺列印left System.out.println(node.e);//每遞迴一次,列印當前根節點 inOrder(node.right);//由淺到深列印right } /* * 二分搜尋樹的後序遍歷(訪問右子樹,左子樹,結點),最自然,最常用的遍歷方式 * */ public void postOrder(){ postOrder(root); } private void postOrder(Node node) { //遞迴的終點 if(node == null){ return; } postOrder(node.left);//列印right由深到淺 postOrder(node.right);//列印left由深到淺 System.out.println(node.e);//最後列印根節點 } /* * 先序中序後序遍歷的列印特點: * 對於每個結點,都有三次訪問,可以用三個點代表三次操作。 * 先序遍歷:打印發生在第一此訪問。 * 中序遍歷:打印發生在第二次訪問。 * 後序遍歷:打印發生在第三次訪問。 */ }

測試程式碼:

package com.lt.datastructure.BST;
/*
 * Binary Search Tree 
 */
public class Main {
    public static void main(String[] args) {
        BST<Integer> bst = new BST<>();
        int[] nums = {5,3,6,8,4,2};
        for(int num : nums){
            bst.add(num);
        }    
        bst.postOrder();
        System.out.println();
    
        bst.preOrder();
        System.out.println();
        
        bst.inOrder();
        System.out.println();
    }
}

三種遍歷的輸出結果:

先序遍歷:

 

中序遍歷:

 

後序遍歷:

 

 三種遍歷的列印順序:

 

 

   

先序中序後序遍歷的列印特點:

  •       對於每個結點,都有三次訪問,可以用三個點代表三次操作。
  •       先序遍歷:打印發生在第一此訪問。
  •       中序遍歷:打印發生在第二次訪問。
  •       後序遍歷:打印發生在第三次訪問。