面试题-二叉树遍历(非递归实现)

一、题目

要求使用非递归的方法,分别实现前、中、后序遍历二叉树。

二、分析

如果使用递归的方法,我们很简单就能实现二叉树的遍历,简单实现一个前序遍历二叉树的例子。

public void recursivePreTree(TreeNode tree) {
    if (tree == null) {
        return;
    }
    System.out.println(tree.value);
    recursivePreTree(tree.left);
    recursivePreTree(tree.right);
}

那么如果不使用递归的方式,我们怎样实现二叉树的遍历呢?

我们需要在遍历的同时,把未遍历完的节点有序的保存下来,同时能够按照在完成一批节点遍历后,按照特定的顺序取出节点进行下一步遍历。而满足这种要求的数据结构就是先进后出的栈。

三、实现

1)前序

1.先将根节点入栈

2.然后访问根节点

3.如果根节点存在右节点,则将右节点入栈

4.如果根节点存在左节点,则将左节点入栈

5.重复2、3、4,直到栈为空并且所有的节点都被访问

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

    TreeNode tmp = tree;

    Stack<TreeNode> stack = new Stack<>();
    stack.push(tmp);

    while (!stack.empty()) {
        TreeNode p = stack.pop();
        System.out.println(p.value);
        
        if (p.right != null) {
            stack.push(p.right);
        }
        
        if (p.left != null) {
            stack.push(p.left);
        }
    }
}

2)中序

扫描二维码关注公众号,回复: 10573479 查看本文章

1.先将根节点入栈

2.将当前节点的所有左节点都入栈,直到左节点为空

3.访问栈顶节点,如果栈顶节点存在右节点,则继续第2步

4.重复第2、3步,直到栈为空并且所有的节点都被访问

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

    TreeNode tmp = tree;

    Stack<TreeNode> stack = new Stack<>();

    while (tmp != null || !stack.empty()) {
        while (tmp != null) {
            stack.push(tmp);
            tmp = tmp.left;
        }

        tmp = stack.pop();

        System.out.println(tmp.value);

        if (tmp.right != null) {
            tmp = tmp.right;
        } else {
            tmp = null;
        }
    }
}

3)后序

1.先将根节点入栈

2.将当前节点的所有左节点都入栈,直到左节点为空

3.访问栈顶节点,判断栈顶节点是否存在右节点,如果存在并且没有被访问,则将右节点入栈,否则,就访问栈顶节点

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

    TreeNode tmp = tree;

    TreeNode prev = null;

    Stack<TreeNode> stack = new Stack<TreeNode>();

    while (tmp != null || !stack.empty()) {
        while (tmp != null) {
            stack.push(tmp);
            tmp = tmp.left;
        }

        if (!stack.empty()) {
            tmp = stack.peek();

            if (tmp.right == null || tmp.right == prev) {
                tmp = stack.pop();

                System.out.println(tmp.value);

                prev = tmp;

                tmp = null;
            } else {
                tmp = tmp.right;
            }
        }
    }
}
发布了43 篇原创文章 · 获赞 0 · 访问量 3914

猜你喜欢

转载自blog.csdn.net/zhangdx001/article/details/105000866