1. 程式人生 > >如何遍歷一棵二叉樹?

如何遍歷一棵二叉樹?

二叉樹的遍歷分為三種:前序遍歷 中序遍歷 後序遍歷

  • 前序遍歷:按照“根左右”,先遍歷根節點,再遍歷左子樹 ,再遍歷右子樹
  • 中序遍歷:按照“左根右“,先遍歷左子樹,再遍歷根節點,最後遍歷右子樹
  • 後續遍歷:按照“左右根”,先遍歷左子樹,再遍歷右子樹,最後遍歷根節點
    其中前,後,中指的是每次遍歷時候的根節點被遍歷的順序
    ============

二叉樹遍歷的java實現

package 樹;

import java.util.ArrayList;
import java.util.List;

public class Tree {
    private Node root;
    private List<Node> list=new ArrayList<Node>();
    public Tree(){
        init();
    }
    //樹的初始化:先從葉節點開始,由葉到根
    public void init(){
        Node x=new Node("X",null,null);
        Node y=new Node("Y",null,null);
        Node d=new Node("d",x,y);
        Node e=new Node("e",null,null);
        Node f=new Node("f",null,null);
        Node c=new Node("c",e,f);
        Node b=new Node("b",d,null);
        Node a=new Node("a",b,c);
        root =a;
    }
    //定義節點類:
    private class Node{
      private String data;
      private Node lchid;//定義指向左子樹的指標
      private Node rchild;//定義指向右子樹的指標
      public Node(String data,Node lchild,Node rchild){
          this.data=data;
          this.lchid=lchild;
          this.rchild=rchild;
      }
    }

    /**
      * 對該二叉樹進行前序遍歷 結果儲存到list中 前序遍歷:ABDXYCEF
      */
     public void preOrder(Node node)
     {

            list.add(node); //先將根節點存入list
            //如果左子樹不為空繼續往左找,在遞迴呼叫方法的時候一直會將子樹的根存入list,這就做到了先遍歷根節點
            if(node.lchid != null)
            {
                preOrder(node.lchid);
            }
            //無論走到哪一層,只要當前節點左子樹為空,那麼就可以在右子樹上遍歷,保證了根左右的遍歷順序
            if(node.rchild != null)
            {
                preOrder(node.rchild);
            }
     }

     /**
      * 對該二叉樹進行中序遍歷 結果儲存到list中
      */
     public void inOrder(Node node)
     {
        if(node.lchid!=null){
            inOrder(node.lchid);
        }
        list.add(node);
        if(node.rchild!=null){
            inOrder(node.rchild);
        }
     }

     /**
      * 對該二叉樹進行後序遍歷 結果儲存到list中
      */
     public void postOrder(Node node)
     {
         if(node.lchid!=null){
             postOrder(node.lchid);
         }
         if(node.rchild!=null){
             postOrder(node.rchild);
         }
         list.add(node);

     }

     /**
      * 返回當前數的深度
      *  說明:
      *  1、如果一棵樹只有一個結點,它的深度為1。
      *  2、如果根結點只有左子樹而沒有右子樹,那麼樹的深度是其左子樹的深度加1;
      *  3、如果根結點只有右子樹而沒有左子樹,那麼樹的深度應該是其右子樹的深度加1;
      *  4、如果既有右子樹又有左子樹,那該樹的深度就是其左、右子樹深度的較大值再加1。
      *  
      * @return
      */
     public int getTreeDepth(Node node) {

            if(node.lchid == null && node.rchild == null)
            {
                return 1;
            }
            int left=0,right = 0;
            if(node.lchid!=null)
            {
                left = getTreeDepth(node.lchid);
            }
            if(node.rchild!=null)
            {
                right = getTreeDepth(node.rchild);
            }
            return left>right?left+1:right+1;
        }


    //得到遍歷結果
     public List<Node> getResult()
     {
      return list;
     }

     public static void main(String[] args) {
        Tree tree=new Tree();
        System.out.println("根節點是:"+tree.root);
        //tree.preOrder(tree.root);
        tree.postOrder(tree.root);
        for(Node node:tree.getResult()){
            System.out.println(node.data);
        }
        System.out.println("樹的深度是"+tree.getTreeDepth(tree.root));

    } 

}





我的總結:

二叉樹是一個相當重要的資料結構,它的應用面非常廣,並且由他改進生成了很多重要的樹類資料結構,如紅黑樹,堆等,應用價值之高後面深入學習便有體會,因此,掌握它的基本特徵和遍歷方式實現是學好後續資料結構的基礎,理論方面其實我們看到二叉樹的形狀,我們自己畫圖都能總結出來,但是程式碼實現這一塊,初學者不是很好理解,樹的遍歷利用了遞迴的思想,遞迴的思想本質無非就是迴圈,方法調方法,所以,理解二叉樹遍歷的程式碼實現最好的方式就是按照它的遍歷思想自己畫出圖來一步一步的遍歷一遍,先把這個遍歷過程想明白了,然後再根據遞迴的思想,什麼時候調什麼樣的方法,自然就能很容易想明白了