常見算法總結 - 二叉樹篇


本文總結了常見高頻的關於二叉樹的算法考察。

1.計算一個給定二叉樹的葉子節點數目。

可以采用遞歸的方式進行累加

public static int calculateTreeNodeNumber(TreeNode treeNode) {

        if (treeNode == null) {
            return 0;
        }

        return calculateTreeNodeNumber(treeNode.left) + calculateTreeNodeNumber(treeNode.right) + 1;

}

2.計算二叉樹的深度。

跟上題一樣采用遞歸的方式,但需返回左右子樹中較深的深度。

public static int getTreeDepth(TreeNode tree) {

        if (tree == null) {
            return 0;
        }

        int left = getTreeDepth(tree.left);
        int right = getTreeDepth(tree.right);

        return left >= right ? left + 1 : right + 1;
}

3.如何打印二叉樹每層的節點。

借助一個隊列,先把根節點入隊,每打印一個節點的值時,也就是打印隊列頭的節點時,都會把它的的左右孩子入隊,並且把該節點出隊。直到隊列為空。

public static void printByLevel(TreeNode tree) {
        if (tree == null) {
            return;
        }

        LinkedList<TreeNode> queue = new LinkedList<>();
        queue.add(tree);
        
        while (!queue.isEmpty()) {
            TreeNode pop = queue.pop();
            System.out.println(pop.val);
            if (pop.left != null) {
                queue.add(pop.left);
            }
            if (pop.right != null) {
                queue.add(pop.right);
            }
        }

}

4.二叉樹的Z型遍歷。

借助兩個隊列,一個正序打印,一個逆序打印。

 public static void printByZ(TreeNode tree) {

        if (tree == null) {
            return;
        }

        List<TreeNode> orderQueue = new ArrayList<>();
        List<TreeNode> disorderQueue = new ArrayList<>();

        orderQueue.add(tree);

        while (!orderQueue.isEmpty()|| !disorderQueue.isEmpty()) {
            if (!orderQueue.isEmpty()) {
              for (int i = 0; i < orderQueue.size(); i++) {
                    TreeNode leaf = orderQueue.get(i);
                    if (leaf.left != null) {
                        disorderQueue.add(leaf.left);
                    }
                    if (leaf.right != null) {
                        disorderQueue.add(leaf.right);
                    }
                }

                for (TreeNode node : orderQueue) {
                    System.out.println(node.val);
                }
                orderQueue.clear();
              
            }


            if (!disorderQueue.isEmpty()) {

                for (int i = 0; i < disorderQueue.size(); i++) {
                    TreeNode leaf = disorderQueue.get(i);
                    if (leaf.left != null) {
                        orderQueue.add(leaf.left);
                    }
                    if (leaf.right != null) {
                        orderQueue.add(leaf.right);
                    }
                }

                for (int i = disorderQueue.size()-1; i >=0 ; i--) {
                    TreeNode leaf = disorderQueue.get(i);
                    System.out.println(leaf.val);
                }
                disorderQueue.clear();
            }
        }

    }

5.一個已經構建好的TreeSet,怎么完成倒排序。

遞歸更換左右子樹即可

public static void reverse(TreeNode tree) {

        if (tree.left == null && tree.right == null) {
            return;
        }

        TreeNode tmp = tree.right;

        tree.right = tree.left;
        tree.left = tmp;

        reverse(tree.left);
        reverse(tree.right);

}

6.二叉樹的前序遍歷。

前序遞歸

public static void preOrderRecursion(TreeNode tree) {

    if (tree != null) {
        System.out.print(tree.val + "->");
        preOrderRecursion(tree.left);
        preOrderRecursion(tree.right);
    }

}

前序非遞歸

public static void preOrderNonRecursion(TreeNode tree) {

        Stack<TreeNode> stack = new Stack<>();
        TreeNode node = tree;
        while (node != null || !stack.empty()) {
            if (node != null) {
                System.out.print(node.val + "->");
                stack.push(node);
                node = node.left;
            } else {
                TreeNode tem = stack.pop();
                node = tem.right;
            }
        }
    }

7.二叉樹的中序遍歷。

中序遞歸

public static void middleOrderRecursion(TreeNode tree) {

        if (tree != null) {
            middleOrderRecursion(tree.left);
            System.out.print(tree.val + "->");
            middleOrderRecursion(tree.right);
        }

}

中序非遞歸

public static void middleOrderNonRecursion(TreeNode tree) {

        Stack<TreeNode> stack = new Stack<>();
        TreeNode node = tree;
        while (node != null || !stack.isEmpty()) {
            if (node != null) {
                stack.push(node);
                node = node.left;
            } else {
                TreeNode tem = stack.pop();
                System.out.print(tem.val + "->");
                node = tem.right;
            }
        }

    }

8.二叉樹的后序遍歷。

后序遞歸

public static void postOrderTraverseRecursion(TreeNode root) {
        if (root != null) {
            postOrderTraverseRecursion(root.left);
            postOrderTraverseRecursion(root.right);
            System.out.print(root.val + "->");
        }
}

后序非遞歸

public static void postOrderTraverseNonRecursion1(TreeNode root) {

        LinkedList<TreeNode> stack = new LinkedList<>();
        LinkedList<TreeNode> output = new LinkedList<>();
        if (root == null) {
            return;
        }

        stack.add(root);
        while (!stack.isEmpty()) {

            TreeNode node = stack.pollLast();
            output.addFirst(node);

            if (node.left != null) {
                stack.add(node.left);
            }
            if (node.right != null) {
                stack.add(node.right);
            }
        }

        for (TreeNode node : output) {
            System.out.print(node.val + "->");
        }

}
筆者個人總結,如有錯誤之處望不吝指出。

本文轉自我的個人博客:《CoderV的進階筆記
歡迎加入Java后端架構技術討論群:1398880
我的公眾號:CoderV的進階筆記,記錄技術心得
qrcode


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM