LeetCode -- 二叉树的先序、中序、后序

223 阅读2分钟

今天是记录leetcode刷题的第二天,今天的题作为回忆二叉树的相关知识。

今日题目来源:

其实,二叉树结构还是比较简答的结构,因为用来用去就是那么两个子节点。

先来说一下二叉树的前序、中序、后序吧。

  • 前序:从根节点出发,先深度优先遍历左子树,在深度优先遍历右子树
  • 中序:先深度优先遍历左子树,再回到根节点,然后在深度优先遍历右子树
  • 后序:先深度优先遍历左子树,在深度优先遍历右子树,最后回到根节点。

可以看到,不论前序、中序还是后序,左右的优先级是不会改变的,都是先左后右,改变的只有根节点的相对位置,所以可以按照以下结论来遍历

  • 前序:{根节点,左子树,右子树}
  • 中序:{左子树,根节点,右子树}
  • 后序:{左子树,右子树,根节点}

在使用代码实现时,树形结构的遍历一般都会使用递归来实现,因为单一的循环是不足以支持两个变量同时循环的,而树有两个节点同时循环。

剩下的就是根据题意将节点值输出或入栈。

代码如下:

public int[][] threeOrders(TreeNode root) {

    if(root == null){
        return new int[3][0];
    }

    Stack<TreeNode> stack = new Stack<>();
    // 先序栈
    eqPreStack(stack, root);
    int size = stack.size();
    // 有size之后,声明
    int[][] treeOrder = new int[3][size];
    // 遍历,放到int[]
    int index = size;
    while (!stack.isEmpty()){
        TreeNode pop = stack.pop();
        treeOrder[0][--index] = pop.val;
    }
    // 中序栈
    eqMidStack(stack, root);
    // 清空栈
    index = size;
    while (!stack.isEmpty()){
        TreeNode pop = stack.pop();
        treeOrder[1][--index] = pop.val;
    }
    eqEndStack(stack, root);
    // 清空栈
    index = size;
    while (!stack.isEmpty()){
        TreeNode pop = stack.pop();
        treeOrder[2][--index] = pop.val;
    }
    return treeOrder;
}


private void eqPreStack(Stack<TreeNode> stack, TreeNode node) {
    stack.add(node);
    if (node.left != null) {
        eqPreStack(stack, node.left);
    }
    if (node.right != null) {
        eqPreStack(stack, node.right);
    }
}

private void eqMidStack(Stack<TreeNode> stack, TreeNode node) {
    if (node.left != null) {
        eqMidStack(stack, node.left);
    }
    stack.add(node);
    if (node.right != null) {
        eqMidStack(stack, node.right);
    }
}

private void eqEndStack(Stack<TreeNode> stack, TreeNode node) {
    if (node.left != null) {
        eqEndStack(stack, node.left);
    }
    if (node.right != null) {
        eqEndStack(stack, node.right);
    }
    stack.add(node);
}

public static class TreeNode {
    int val = 0;

    public TreeNode(int val) {
        this.val = val;
    }

    TreeNode left = null;

    TreeNode right = null;
}

测试案例:

// 需要自备测试依赖,或将测试方法改为main方法
@Test
public void test(){
    TreeNode node = new TreeNode(1);
    node.left = new TreeNode(2);
    node.right = new TreeNode(3);
    threeOrders(node);
}

附newcode截图

image.png