二叉树的非递归后序遍历算法实例详解


Posted in Javascript onFebruary 07, 2014

前序、中序、后序的非递归遍历中,要数后序最为麻烦,如果只在栈中保留指向结点的指针,那是不够的,必须有一些额外的信息存放在栈中。
方法有很多,这里只举一种,先定义栈结点的数据结构

typedef struct{Node * p; int rvisited;}SNode //Node 是二叉树的结点结构,rvisited==1代表p所指向的结点的右结点已被访问过。
lastOrderTraverse(BiTree bt){

//首先,从根节点开始,往左下方走,一直走到头,将路径上的每一个结点入栈。

p = bt;

while(bt){


push(bt, 0); //push到栈中两个信息,一是结点指针,一是其右结点是否被访问过


bt = bt.lchild;

}

//然后进入循环体

while(!Stack.empty()){ //只要栈非空


sn = Stack.getTop(); // sn是栈顶结点


//注意,任意一个结点N,只要他有左孩子,则在N入栈之后,N的左孩子必然也跟着入栈了(这个体现在算法的后半部分),所以当我们拿到栈顶元素的时候,可以确信这个元素要么没有左孩子,要么其左孩子已经被访问过,所以此时我们就不关心它的左孩子了,我们只关心其右孩子。


//若其右孩子已经被访问过,或是该元素没有右孩子,则由后序遍历的定义,此时可以visit这个结点了。


if(!sn.p.rchild || sn.rvisited){



p = pop();



visit(p);


}


else //若它的右孩子存在且rvisited为0,说明以前还没有动过它的右孩子,于是就去处理一下其右孩子。


{ 



//此时我们要从其右孩子结点开始一直往左下方走,直至走到尽头,将这条路径上的所有结点都入栈。



//当然,入栈之前要先将该结点的rvisited设成1,因为其右孩子的入栈意味着它的右孩子必将先于它被访问(这很好理解,因为我们总是从栈顶取出元素来进行visit)。由此可知,下一次该元素再处于栈顶时,其右孩子必然已被visit过了,所以此处可以将rvisited设置为1。



sn.rvisited = 1;



//往左下方走到尽头,将路径上所有元素入栈



p = sn.p.rchild;



while(p != 0){




push(p, 0);




p = p.lchild;



}


}//这一轮循环已结束,刚刚入栈的那些结点我们不必管它了,下一轮循环会将这些结点照顾的很好。

}
}
Javascript 相关文章推荐
Opacity.js
Jan 22 Javascript
javascript学习笔记(十四) window对象使用介绍
Jun 20 Javascript
HTML5canvas 绘制一个圆环形的进度表示实例
Dec 16 Javascript
bootstrap css样式之表单
Jan 19 Javascript
JS实现匀加速与匀减速运动的方法示例
Sep 04 Javascript
js断点调试心得分享(必看篇)
Dec 08 Javascript
微信小程序数据存储与取值详解
Jan 30 Javascript
React props和state属性的具体使用方法
Apr 12 Javascript
玩转vue的slot内容分发
Sep 22 Javascript
vue项目中使用Svg的方法
Oct 24 Javascript
使用taro开发微信小程序遇到的坑总结
Apr 08 Javascript
vue+element-ui+axios实现图片上传
Aug 20 Javascript
Select标签下拉列表二级联动级联实例代码
Feb 07 #Javascript
javascript运行机制之this详细介绍
Feb 07 #Javascript
jQuery获取当前对象标签名称的方法
Feb 07 #Javascript
JQuery与Ajax调用新浪API获取短网址的代码
Feb 07 #Javascript
jquery Ajax 实现加载数据前动画效果的示例代码
Feb 07 #Javascript
jquery.ajax的url中传递中文乱码问题的解决方法
Feb 07 #Javascript
jquery ajax传递中文参数乱码问题及解决方法说明
Feb 07 #Javascript
You might like
php5 图片验证码实现代码
2009/12/11 PHP
关于使用coreseek并为其做分页的介绍
2013/06/21 PHP
不使用php api函数实现数组的交换排序示例
2014/04/13 PHP
PHP使用ob_start生成html页面的方法
2014/11/07 PHP
PHP中遇到的时区问题解决方法
2015/07/23 PHP
PHP之浮点数计算比较以及取整数不准确的解决办法
2015/07/29 PHP
Ajax提交表单时验证码自动验证 php后端验证码检测
2016/07/20 PHP
PHP解耦的三重境界(浅谈服务容器)
2017/03/13 PHP
PHP面向对象之工作单元(实例讲解)
2017/06/26 PHP
(currentStyle)javascript为何有时用style得不到已设定的CSS的属性
2007/08/15 Javascript
javascript 建设银行登陆键盘
2008/06/10 Javascript
解析瀑布流布局:JS+绝对定位的实现
2013/05/08 Javascript
js实现点击注册按钮开始读秒倒计时的小例子
2013/05/11 Javascript
Node.js中使用Buffer编码、解码二进制数据详解
2014/08/16 Javascript
详解AngularJS的通信机制
2015/06/18 Javascript
JS实现的5级联动Select下拉选择框实例
2015/08/17 Javascript
Layui 导航默认展开和菜单栏选中高亮设置的方法
2019/09/04 Javascript
element-ui 远程搜索组件el-select在项目中组件化的实现代码
2019/12/04 Javascript
js实现时间日期校验
2020/05/26 Javascript
vue element-ui中table合计指定列求和实例
2020/11/02 Javascript
[03:40]DOTA2亚洲邀请赛小组赛第二日 赛事回顾
2015/01/31 DOTA
[42:52]Optic vs Serenity 2018国际邀请赛淘汰赛BO3 第二场 8.22
2018/08/23 DOTA
python使用arcpy.mapping模块批量出图
2017/03/06 Python
python操作MySQL 模拟简单银行转账操作
2017/09/27 Python
python里使用正则表达式的组嵌套实例详解
2017/10/24 Python
Python拼接微信好友头像大图的实现方法
2018/08/01 Python
python实现词法分析器
2019/01/31 Python
python 实现检验33品种数据是否是正态分布
2019/12/09 Python
Django中和时区相关的安全问题详解
2020/10/12 Python
教学大赛获奖感言
2014/01/15 职场文书
喜之郎果冻广告词
2014/03/20 职场文书
售后服务承诺书模板
2014/05/21 职场文书
领导干部作风建设总结
2014/10/23 职场文书
行为习惯主题班会
2015/08/14 职场文书
分析JVM源码之Thread.interrupt系统级别线程打断
2021/06/29 Java/Android
JavaScript选择器函数querySelector和querySelectorAll
2021/11/27 Javascript