二叉樹的遍歷

二叉樹的性質

1,二叉樹的第i層最多包含2*i-1個節點。

2,二叉樹如果深度爲k(有k層),那麼最多含有(2^k )-1個節點。

3,若二叉樹按照從上到下從左到右的方式編號,某節點的編號爲k,那麼他的左右子樹分別編號爲2k,2k+1.

4,二叉樹分類:滿二叉樹,完全二叉樹,平衡二叉樹。

滿二叉樹:除了葉子結點以外所有的結點都必須滿足度最大,即,一個深度爲k的滿二叉樹,其包含的葉子結點數爲(2^k )-1。滿二叉樹即每個非葉子節點的左右子樹均在。

完全二叉樹:除了深度最大的一層以外,其他每層結點都必須均在,層數爲k的完全二叉樹的每個節點的編號,與層數爲k的滿二叉樹的結點編號一一對應。

滿二叉樹必爲完全二叉樹,完全二叉樹不一定爲滿二叉樹。

二叉樹的創建:

  public static Tree createTree(int [] array){
        ArrayList<Tree> list = new ArrayList<>();

        for (int i = 0; i < array.length; i++) {
            list.add(new Tree(array[i]));
        }
        Tree root = list.get(0);
        for (int i = 0; i < list.size()/2; i++) {
            list.get(i).setLeft(list.get(2*i + 1));

            if(i*2 + 2 < list.size()){
                list.get(i).setRight(list.get(2*i + 2));
            }
        }
        return root;
    }

二叉樹的遍歷:  

深度優先,廣度優先

前序中序和後序。

深度優先遍歷使用棧,廣度優先遍歷使用隊列。

 public static void  DepthFirstSearch(Tree root){
        Stack<Tree>  stack = new Stack<>();

        stack.push(root);
        while(!stack.empty()){
            Tree temp = stack.pop();
            System.out.println(temp.getVal());
            if(temp.getRight() != null){
                stack.push(temp.getRight());
            }

            if(temp.getLeft() != null){
                stack.push(temp.getLeft());
            }
        }
//原樹  6 5 4 3 2 1 0

//6 5 3 2 4 1 0 

   深度優先即先左後右,則在遍歷的時候,現將根節點打印之後,將根節點的右子樹壓入棧中,再將左子樹壓入棧中。利用棧的性質進行遍歷。

廣度優先使用隊列,先進先出。

 public static void breadthFirstSearch(Tree root){
            Queue<Tree> queue = new LinkedList<>();

            queue.offer(root);
            while(queue.size() != 0){
                Tree temp = queue.poll();  //取出第一個元素並刪除
                System.out.print(temp.getVal() + " ");

                if(temp.getLeft() != null){
                    queue.offer(temp.getLeft());
                }

                if(temp.getRight() != null){
                    queue.offer(temp.getRight());
                }
            }
    }

   先序遍歷:根 ->左->右     和深度遍歷一致。

   中序遍歷:左 ->根->右

   後序遍歷 :左->右->跟     

//二叉樹中序遍歷  左 根 右
public static void  inorderTraversal(Tree root){
        if(root == null){
            return;
        }

        Stack<Tree> stack = new Stack<Tree>();
        Tree p = root;

        while(p != null || !stack.empty()){

            while(p != null){
                stack.push(p);
                p = p.getLeft();
            }//將該節點壓入棧並且其所有左結點都壓入

            p = stack.pop();
            System.out.print(p.getVal() + " ");
            p = p.getRight();
        }
    }

                    

// 二叉樹後序遍歷
  public static void  postOrderTraversal(Tree root){
        if(root == null){
            return;
        }
        //利用兩個棧  對於第一個棧入得順序是跟左右  入第二個棧的順序是  跟右左  出棧順序 左右根
        Stack<Tree> stack1 = new Stack<>();
        Stack<Tree> stack2 = new Stack<>();
        stack1.push(root);

        while(!stack1.empty()){
            Tree node = stack1.pop();
            stack2.push(node);

            if(node.getLeft() != null){
                stack1.push(node.getLeft());
            }

            if(node.getRight() != null){
                stack1.push(node.getRight());
            }
        }


        while(!stack2.empty()){
            System.out.print(stack2.pop().getVal() + " ");
        }

    }

                                                                                   

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章