二叉树遍历的非递归算法

  闲来无事,重看了《数据结构》一书,突然发现其中的很多代码写的很精妙,以下就是我对二叉树一部分的做的记录。一般遍历就是使用前序、中序、后序三种遍历,我自己平时都是使用递归算法,今天看书才发现递归算法不是最优解,因为函数调用栈层层叠加,还要保存函数的返回地址,实际参数传递,创建局部变量等等。

  一、二叉树前序非递归算法

    前序遍历的特点是:首先访问根,访问完根后再访问左子树,所以对每一个结点,在访问完该结点后,沿着左链访问下来 ,直到为左链为空,然后将所有访问过的结点进栈。然后结点出栈,每一个出栈的结点就是表示该结点和期左子树都已经被访问,那么开始访问该结点的右子树了。

    步骤如下:

      1.当前指针指向根结点。

      2.打印当前结点,当前指针指向其左孩子结点并进栈,重复(2),直至左孩子为Null.

      3.依次退栈,将当前指针指向右孩子结点。

      4.若栈非空或者当前指针非Null,执行(2),否则结束.

    代码如下 c语言版本:

      void  Bit_PreOder(BitNode *root)

      {

        BitNode *p, * node[max];

        int top=0;p=root;

        do

         {while (p!=null)

          {printf("%d, ",p->data) ; node[top=p] ; top++; p=p->lch ;}    /* lch是指左子结点,rch是指右子节点 */

          if (top>0)

           { top-- ; p=node[top] ; p=p->rch ; }                 /*   凡是退栈的指针,其所指的结点及其左子树,都已遍历 */

         }while (top>0 || p!=null)

      }

*   注意:以上代码已经过测试,可以使用。

时间: 2024-10-17 23:45:56

二叉树遍历的非递归算法的相关文章

数据结构算法实现-二叉树遍历的非递归算法

由于递归算法使用系统堆栈,性能较差,所以应尽可能使用非递归算法. 1.先序遍历 先序遍历,即得到节点时输出数据. // 先序遍历 function PreOrder(node){ if(node!==undefined){ console.log(node.data) } var stack=[] //模仿递归的栈 stack.push(node) for(var temp=node,i=0;temp!==undefined;temp=stack[stack.length-1]){ if(tem

二叉树3种遍历的非递归算法

http://blog.csdn.net/pipisorry/article/details/37353037 c实现: 1.先序遍历非递归算法 #define maxsize 100 typedef struct { Bitree Elem[maxsize]; int top; } SqStack; void PreOrderUnrec(Bitree t) { SqStack s; StackInit(s); p=t; while (p!=null || !StackEmpty(s)) { w

二叉树的广义表创建及中序遍历、后序遍历、层次遍历的非递归算法(C语言)

广义表创建二叉树关于用广义表的形式表示二叉树的形式如下 ①广义表中的一个字母代表一个结点的数据信息.②每个根结点作为由子树构成的表的名字放在义表的前面.③每个结点的左子树与右子树之间用逗号分开.若结点只有右子树面无左子树,则该逗号不能省略.④在整个广义表的末尾加一个特殊符号(如“@”)作为结束标志. 下面先用自然语言描述算法如下.依次从广义表中取得-个元素,并对取得的元素做如下相应的处理. ①若当前取得的元素为字母,则按如下规则建立一个新的(链)结点.a)若该结点为二叉树的根结点,则将该结点的地

二叉树的前序建立,前中后序遍历的非递归算法

二叉树的前序建立递归算法以及前中后序遍历的递归算法已经是人尽皆知了,递归算法也确实为代码的编写带来了很大的方便.然而,有时我们也确实需要它们的非递归算法.将递归算法转化为非递归算法可以帮助我们深入了解函数的调用与栈的原理.这里总结一下二叉树的这些重要的非递归算法. 一.前序建树 前序建树的基本思路是,接收用户输入的一组字符串,其中'#'代表空树,其他代表树结点的数据域值.例如,要建立如下一棵树 需要输入"AB#D##C##". 而非递归的思路是,1.设一个标志位来判断当前创建的结点是左

JAVA语言实现二叉树的层次遍历的非递归算法及递归算法

/** 二叉树节点 */ public class BTNode { private char key; private BTNode left, right; public BTNode(char key) { this(key, null, null); } public BTNode(char key, BTNode left, BTNode right) { this.key = key; this.left = left; this.right = right; } public ch

java数据结构之二叉树遍历的非递归实现

算法概述递归算法简洁明了.可读性好,但与非递归算法相比要消耗更多的时间和存储空间.为提高效率,我们可采用一种非递归的二叉树遍历算法.非递归的实现要借助栈来实现,因为堆栈的先进后出的结构和递归很相似.对于中序遍历来说,非递归的算法比递归算法的效率要高的多.其中序遍历算法的实现的过程如下:(1).初始化栈,根结点进栈:(2).若栈非空,则栈顶结点的左孩子结点相继进栈,直到null(到叶子结点时)退栈:访问栈顶结点(执行visit操作)并使栈顶结点的右孩子结点进栈成为栈顶结点.(3).重复执行(2),

二叉树遍历的非递归

前序遍历的非递归:1.在入栈时增加结果集,不停的取左子树入栈.直到为空.2.假设栈非空,pop栈顶结点.取其右子树作为当前结点,继续第一步.直到栈为空 中序遍历的非递归:1.在入栈时,不停的取左子树入栈,直到为空.2.假设栈非空,pop栈顶结点,增加结点集,取其右子树作为当前结点.继续第一步.直到栈为空 后序遍历的非递归:1.在遍历结点时,总是先将右子树结点入栈,再将左子树结点入栈. 2.假设左子树结点和右子树结点为空或者右子树结点已经訪问过,弹出栈顶元素,标记已訪问结点.增加结果集.直到栈为空

二叉树后序遍历的非递归算法(C语言)

首先非常感谢‘hicjiajia’的博文:二叉树后序遍历(非递归) 这篇随笔开启我的博客进程,成为万千程序员中的一员,坚持走到更远! 折磨了我一下午的后序遍历中午得到解决,关键在于标记右子树是否被访问过,考虑过修改二叉树结点的数据结构,增加一个visit域,或者建一个栈存储已访问的结点.都比较麻烦没有调试成功.若将右子树也入栈,如果没有访问标记的话,会改变访问的次序,甚至出现死循环,这是比较危险的情况.从借鉴的博文里,摘录并改写为C的代码,基本上没有改动.后续问题努力写出自己的原创代码. 二叉树

二叉树--后序遍历的非递归算法

后续遍历关键在于,当节点的  右子树存在且被访问后  或者是  右子树为空  才能访问自身. 在遍历过程中,先将节点从的左孩子到最左节点压栈, 设置标志变量 flag 来判断是否访问过左孩子, pre指针来指向先前访问过的节点. 所有左孩子压栈后, 最后一个节点的左孩子为空,已被访问p = NULL , 令flag=1 当左孩子被访问时,进入循环,取栈顶节点. 1. 当栈顶节点的右孩子 等于 空  或  前一个被访问的节点  时, 访问该节点, 令pre 等于当前节点,pre = p, 当前节点