劍指offer—二叉樹的深度

題目:

輸入一棵二叉樹,求該樹的深度。從根結點到葉結點依次經過的結點(含根、葉結點)形成樹的一條路徑,最長路徑的長度爲樹的深度。

題中定義了二叉樹的深度爲:最長的一條路徑長度即爲樹的深度。

可以分爲幾種情況:

  1. 如果樹只有左子樹,沒有右子樹,則樹的深度應該爲左子樹深度+1。
  2. 如果樹只有右子樹,沒有左子樹,則樹的深度爲右子樹深度+1。
  3. 如果樹既有左子樹又有右子樹,則整個樹的深度爲max(左子樹深度,右子樹深度)+1。

1. 遞歸方法

根據以上思路可以寫出遞歸版本的求解二叉樹的深度:

public class Solution {
    public int TreeDepth(TreeNode root) {
        if(root == null){
            return 0;
        }
        if(root.left == null && root.right != null){
            return TreeDepth(root.right)+1;
        }else if(root.left != null && root.right == null){
            return TreeDepth(root.left)+1;
        }else{
            return Math.max(TreeDepth(root.left),TreeDepth(root.right))+1;
        }
    }
}

2. 非遞歸版本

上面遞歸版本是計算每一條路徑的節點數,和深度搜索有點像。如果不是一條路徑執行到底,而是一層一層的往外遍歷呢?
一層一層遍歷,想到了什麼?
廣度優先搜索,聯繫到二叉樹,也就是層序遍歷,層序遍歷是借用輔助空間隊列。每次拉出一個節點之後,將該節點的左右子節點添加到隊列中。只是本題中需要每次記住層次。

怎麼知道這一層遍歷完了呢?
利用兩個數據,num、nextNum,前者表示當前層遍歷到第幾個元素,後者便是本層元素個數(或者說下一層元素個數)。
具體的流程如下:
在這裏插入圖片描述





import java.util.*;
public class Solution {
    public int TreeDepth(TreeNode root) {
        if(root == null){
            return 0;
        }
        Queue<TreeNode> nodes = new LinkedList<TreeNode>();
        nodes.add(root);
        int level = 0;
        int num = 0;
        int nextNum = 1;
        while(nodes.size() != 0){
            TreeNode top = nodes.poll();
            num++;
            if(top.left != null){
                nodes.add(top.left);
            }
            if(top.right != null){
                nodes.add(top.right);
            }
            // 如果這個if條件成立,則說明本層所有的節點已經全部彈出,則將nextNum更新爲下一層節點個數
            if(num == nextNum){
                nextNum = nodes.size();
                num = 0;
                level++;
            }
        }
        return level;
    }
}

總結

求解二叉樹的深度,遞歸方法比較簡單,循環方法稍稍複雜,但是只需要掌握了層次遍歷的核心(藉助隊列),問題自然簡單了很多。
一定要熟悉各種不同遍歷方式的輔助工具。

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