美文网首页
二叉树的非递归遍历

二叉树的非递归遍历

作者: KM_0d16 | 来源:发表于2019-04-27 22:59 被阅读0次

引言

前面的文章已经介绍了二叉树的递归遍历,本章介绍二叉树的非递归方式,主要是通过栈来实现,通常来讲非递归的方式在时间复杂度方面会优于递归的方式(凡事无绝对),下面介绍三种遍历方式的非递归实现


图一

一、先序遍历非递归实现

  1. 结点1入栈
  2. 出栈,输出栈顶结点1,并将1的左、右孩子结点(2和4)入栈;右孩子先入栈,左孩子后入栈,因为对左孩子的访问要先于右孩子,后入栈的会先出栈访问。
  3. 出栈,输出栈顶结点2,并将2的左、右孩子结点(3和5)入栈。
  4. 出栈,输出栈顶结点3,3为叶子结点,无孩子,本步无结点入栈
  5. 出栈,输出栈顶结点5
  6. 出栈,出栈,输出栈顶结点4
    先序遍历结点进出栈过程
    由此我们可得到代码
public static void preOrderNo(BTNode node) {
        if (node != null) {
            ArrayDeque<BTNode> stack = new ArrayDeque<>();
            //根节点进栈
            stack.push(node);
            while (!stack.isEmpty()) {
                BTNode nodeTemp = stack.pop();
                System.out.print(nodeTemp.data + " ");
                //右结点先入栈
                if (nodeTemp.rightChild != null) {
                    stack.push(nodeTemp.rightChild);
                }
                if(nodeTemp.leftChild != null) {
                    stack.push(nodeTemp.leftChild);
                }
            }
        }
    }

我们可以发现,遍历的方式和层次遍历非常相像,只是层次遍历使用的是队列,而且左孩子先入队列。

二、中序遍历非递归实现

中序遍历和先序遍历有些不同,我们需先将左孩子结点全部入栈,结合中序遍历的结果来看也合理,因为第一个中序遍历的第一个元素一定是最左端的结点元素


中序遍历
  1. 先将左孩子入栈
  2. 左孩子出栈,出栈时检测有无右孩子,如果存在,则入栈
    注意一开始根节点不入栈
    需要注意的是在6->7步骤的过程中,栈是为空的,检测是写在循环之后的,这一点在代码中有体现,需要额外加入一个判断维持循环继续
public static void inOrderNo(BTNode node) {
       if (node != null) {
           ArrayDeque<BTNode> stack = new ArrayDeque<>();
           BTNode p = node;
           //加入p != null是因为,如图中第7步骤,当根节点出栈时,栈为空,但是循环还没有结束,
           // 因为右结点4还没有添加进去,所以添加这一条件维持循环
           while(!stack.isEmpty() || p != null){
               //将左孩子全部入栈,需要注意的是右孩子也是通过这里入栈的
               while (p != null) {
                   stack.push(p);
                   p = p.leftChild;
               }
       
                   p = stack.pop();
                   System.out.print(p.data + " ");
                   p = p.rightChild;
               
           }
       }
    }

三、后序遍历非递归实现

首先根据文章开头图一手工写出先序遍历和后续遍历
先序:12354
后序:35241
将后序遍历逆序得到:14253
可以发现后序不过是先序遍历过程中对左右子树遍历顺序交换所得到的结果
由此我们可以得到后序遍历的过程。
1.交换先序遍历中获取左右子树的顺序
2.实现逆序输出(使用新的一个栈即可)
实现代码:

    public static void postOrderNo(BTNode node) {
        if (node != null) {
            ArrayDeque<BTNode> stack = new ArrayDeque<>();
            ArrayDeque<BTNode> postStack = new ArrayDeque<>();
            //根节点进栈
            stack.push(node);
            while (!stack.isEmpty()) {
                BTNode nodeTemp = stack.pop();
                postStack.push(nodeTemp);
                //左孩子先入栈
                if(nodeTemp.leftChild != null) {
                    stack.push(nodeTemp.leftChild);
                }
                if (nodeTemp.rightChild != null) {
                    stack.push(nodeTemp.rightChild);
                }
            }

            //依次输出postStack即可实现逆序
            while (!postStack.isEmpty()) {
                BTNode postNode = postStack.pop();
                System.out.print(postNode.data + " ");
            }
        }
    }

相关文章

  • 二叉树遍历java,非递归、层次。

    /** * 前序遍历 * 递归 */ /*** 前序遍历* 非递归*/ 后续遍历非递归 二叉树层次遍历基于java...

  • 二叉树递归非递归遍历算法整理

    一、二叉树前序遍历 1 前序递归遍历 2.前序非递归遍历 一、二叉树中序遍历 2.中序递归遍历 1.中序非递归遍历...

  • 总结

    1、二叉树广度遍历(非递归) 广度遍历非递归实现需要依靠一个队列。 2、二叉树深度遍历(递归与非递归,前序,中序和...

  • 二叉树遍历

    二叉树的遍历 1. 前序遍历 1.1 递归前序遍历 1.2 非递归前序遍历 2 中序遍历 2.1递归遍历 2.2非...

  • 二叉树,非递归法

    递归法 二叉树的递归,有前序遍历、中序遍历、后序遍历,一般采用递归法,比较简单 非递归法 二叉树非递归法,采用栈来实现

  • 二叉树遍历-JAVA实现

    基础二叉树 二叉树遍历分为前序、中序、后序递归和非递归遍历、还有层序遍历。 前序递归遍历算法:访问根结点-->递归...

  • 算法之二叉树

    二叉树之C++实现 创建二叉树 复制二叉树 先序遍历 递归实现 非递归实现 中序遍历 递归实现 非递归实现 后序遍...

  • 二叉树遍历

    请递归,非递归方式分别前序遍历,中序遍历,后续遍历二叉树

  • LeetCode 二叉树的中序遍历(递归和非递归算法)

    二叉树的中序遍历给定一个二叉树,返回它的中序 遍历。示例: 非递归(思路更清晰): 非递归: 递归:

  • 二叉树

    结构体 创建二叉树 递归遍历 栈操作 非递归遍历 层次遍历 完整代码

网友评论

      本文标题:二叉树的非递归遍历

      本文链接:https://www.haomeiwen.com/subject/vvuknqtx.html