二叉樹遍歷(前、中、後序及層序遍歷)

二叉樹的遍歷

所謂遍歷(Traversal)是指沿着某條搜索路線,依次對樹中每個節點均做一次且僅做一次的訪問。訪問節點所做的操作依賴於具體的應用問題。遍歷是二叉樹上最重要的運算之一。是二叉樹上進行其它運算的基礎。

如何將所有節點都遍歷打印出來?經典的方法有三種:前序遍歷、中序遍歷、後序遍歷。除此之外,還有按層遍歷。其中,前、中、後序表示的是節點和它左右子樹節點遍歷打印的先後順序。

  • 前序遍歷是指,對樹中的任意節點,先打印這個節點本身,然後再打印它的左子樹,最後打印它的右子樹。
  • 中序遍歷是指,對樹中的任意節點,先打印它的左子樹,然後再打印這個節點本身,最後打印它的右子樹。
  • 後序遍歷是指,對樹中的任意節點,先打印它的左子樹,然後再打印它的右子樹,最後打印這個節點本身。
  • 層次遍歷是指,從第一層(根節點)開始,從上到下一層一層遍歷,同層之間按從左到右的順序依次遍歷節點。亦稱之爲廣度優先遍歷。

實際上,二叉樹的前、中、後序遍歷就是一個遞歸的過程。比如,前序遍歷就是先打印根節點,然後再遞歸的打印左子樹,最後遞歸的打印右子樹。

二叉樹的前、中、後序遍歷的遞歸實現:

/** Java版
*  public class TreeNode{
*    int val;
*    TreeNode left;
*    TreeNode right;
*    TreeNode(int x){ val = x; }
*/

// 前序遍歷
public void preOrder(TreeNode root){
    if(root == null) return;
    System.out.print(root.val);
    preOrder(root.left);
    preOrder(root.right);
}

// 中序遍歷
public void inOrder(TreeNode root){
    if(root == null) return;
    inOrder(root.left);
    System.out.print(root.val);
    inOrder(root.right);
}

// 後序遍歷
public void postOrder(TreeNode root){
    if(root == null) return;
    postOrder(root.left);
    postOrder(root.right);
    System.out.print(root.val);
}

拓展: 二叉樹的層序遍歷

二叉樹層序遍歷的核心問題是二維結構的線性化。我們通過節點訪問其左右子節點時,存在的問題是訪問左子節點後,右子節點如何訪問。因此我們需要一個存儲結構保存暫時不訪問的節點。事實上我們可以通過隊列來保存。

       隊列實現的思路是:

遍歷從根節點開始,首先判斷頭結點不爲空

然後先將根節點入隊,然後從根節點判斷左右子節點

然後出隊隊首元素

隊列的作用就是將二叉樹按照 根節點,左子樹,右子樹的順序接受然後出隊操作

最終隊列爲空的時候跳出循環,達到層序遍歷的目的。

/**
* @author: Aero
* @Date: 2019/09/04 20:20
* @version: 1.0
* 層序遍歷二叉樹
* public class TreeNode{
*    int val;
*    TreeNode left;
*    TreeNode right;
*    TreeNode(int x){ val = x; 
* }
*/
public List<List<Integer>> levelOrder(TreeNode root) {
     List<List<Integer>> list = new ArrayList<>();
     if(root == null)
         return list;
     Queue<TreeNode> queue = new LinkedList<>();
     queue.add(root);
     queue.add(null);
     int num = 0;
     List<Integer> tempList = new ArrayList<>();
     list.add(tempList);
     while(!queue.isEmpty()) {
         TreeNode temp = queue.poll();
         if(temp != null) {
            list.get(num).add(temp.val);
            if(temp.left != null)
               queue.add(temp.left);
               if(temp.right != null)
                  queue.add(temp.right);
            }else {
               if(!queue.isEmpty()) {
                 num++;
                 tempList = new ArrayList<>();
                 list.add(tempList);
                 queue.add(null);
               }
            }
         }
     }
     return list;
}

 

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