1. 程式人生 > 實用技巧 >【力扣】104. 二叉樹的最大深度-及二叉樹的遍歷方式

【力扣】104. 二叉樹的最大深度-及二叉樹的遍歷方式

給定一個二叉樹,找出其最大深度。

二叉樹的深度為根節點到最遠葉子節點的最長路徑上的節點數。

說明:葉子節點是指沒有子節點的節點。

示例:
給定二叉樹 [3,9,20,null,null,15,7],

3
/ \
9 20
/ \
15 7
返回它的最大深度3 。

來源:力扣(LeetCode)
連結:https://leetcode-cn.com/problems/maximum-depth-of-binary-tree

public class TreeNode {



    public int val;
    public TreeNode left;
    
public TreeNode right; public TreeNode(int x) { val = x; } }

解法1:遞迴

public int maxDepth(TreeNode root) {
        if (root == null){
            return 0;
        }
        return Math.max(maxDepth(root.left),maxDepth(root.right)) + 1;
    }

藉此學習下二叉樹的遍歷方法:

二叉樹有兩種遍歷方式,第一種是深度優先遍歷演算法,深度優先又分為前序遍歷、中序遍歷、後序遍歷,第二種是廣度優先遍歷演算法,也就是層次遍歷

前序遍歷:1 2 4 5 7 8 3 6

中序遍歷:4 2 7 5 8 1 3 6

後序遍歷:4 7 8 5 2 6 3 1

層次遍歷:1 2 3 4 5 6 7 8

深度優先:

深度優先中的前序遍歷:根結點 ---> 左子樹 ---> 右子樹

/**
     * 二叉樹的深度優先遍歷演算法中的前序遍歷 (遞迴)
     */
    public List preOrder(TreeNode root) {
        if (root == null){
            return null;
        }
        List<Integer> list = new
ArrayList<>(); search(list,root); return list; } public void search(List<Integer> list,TreeNode root){ if (root != null){ list.add(root.val); search(list,root.left); search(list,root.right); } }

/**
     * 二叉樹的深度優先遍歷演算法中的前序遍歷 使用棧
     *
     */
    public List preOrderUseStack(TreeNode root) {
        if (root == null){
            return null;
        }
        List<Integer> list = new ArrayList<>();
        Stack<TreeNode> stack = new Stack();   //也可以用棧實現 棧的特性是先進後出
        stack.push(root);

        //若棧不空
        while(!stack.isEmpty()){
            //取出響應的節點
            TreeNode node=stack.pop();
            list.add(node.val);

            //考慮到先進後出的特性,所以先放右子節點
            if(node.right!=null){
                stack.push(node.right);
            }
            if(node.left!=null){
                stack.push(node.left);
            }
        }
        return list;
    }

深度優先中的中序遍歷:左子樹 --->根結點 ---> 右子樹
/**
     * 中序遍歷
     */
    public List centerOrderUseStack(TreeNode root) {
        if (root == null){
            return null;
        }
        List<Integer> list = new ArrayList<>();
        Stack<TreeNode> stack = new Stack();   //也可以用棧實現 棧的特性是先進後出
        TreeNode currentNode = root;

        //若棧不空
        while(currentNode != null || !stack.isEmpty()){
            while(currentNode != null){
                stack.push(currentNode);
                currentNode = currentNode.left;
            }
            //取出響應的節點
            currentNode=stack.pop();
            list.add(currentNode.val);
            currentNode = currentNode.right;
        }
        return list;
    }

深度優先中的後序遍歷:左子樹---> 右子樹--->根結點
/**
     * 後序遍歷,後序遍歷的特殊點在於我們要最後獲取到根節點  還是很複雜的!!!!!!
     */
    public List afterWordUseStack(TreeNode root) {
        if (root == null){
            return null;
        }
        List<Integer> list = new ArrayList<>();
        Stack<TreeNode> stack = new Stack();   //也可以用棧實現 棧的特性是先進後出
        TreeNode currentNode = root;
        TreeNode rightNode = null;
        //若棧不空
        while(currentNode != null || !stack.isEmpty()){
            //一直迴圈到最左端的葉子結點(currentNode是null)
            while(currentNode != null){
                stack.push(currentNode);
                currentNode = currentNode.left;
            }
            //取出相應的節點
            currentNode=stack.pop();
            //若右節點是空,或者 當前節點的右節點為右節點  這樣迴圈完成可以得到currentNode 父節點
            while(currentNode.right == null || currentNode.right == rightNode){
                list.add(currentNode.val);
                rightNode = currentNode; // 設定右節點為當前節點

                if (stack.isEmpty()){
                    return list;
                }
                currentNode=stack.pop();
            }
            stack.push(currentNode); //還有右結點沒有遍歷
            currentNode = currentNode.right;
        }
        return list;
    }

廣度優先:

/**
     * 廣度優先遍歷 又稱層級遍歷 需要藉助資料結構 : 佇列
     */
    public List spanUseStack(TreeNode root) {
        if (root == null){
            return null;
        }

        //佇列的特性為:先進先出
        ArrayDeque<TreeNode> deque = new ArrayDeque<TreeNode>();
        List<Integer> list = new ArrayList<>();
        deque.add(root);

        while(!deque.isEmpty()){
            TreeNode current = deque.remove();
            list.add(current.val);
            if (current.left != null){
                deque.add(current.left);
            }
            if (current.right != null){
                deque.add(current.right);
            }
        }
        return list;
    }