常见算法总结 - 二叉树篇

648 阅读2分钟

本文总结了常见高频的关于二叉树的算法考察。

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