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


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 相关文章推荐
静态图片的十一种滤镜效果--不支持Ie7及非IE浏览器。
Mar 06 Javascript
jQuery下通过$.browser来判断浏览器.
Apr 05 Javascript
jQuery为iframe的body添加click事件的实现代码
Apr 07 Javascript
js中关于一个分号的崩溃示例
Nov 11 Javascript
JavaScript中的值类型转换介绍
Dec 31 Javascript
jquery实现简单的自动播放幻灯片效果
Jun 13 Javascript
Bootstrap php制作动态分页标签
Dec 23 Javascript
ES6中字符串string常用的新增方法小结
Nov 07 Javascript
利用babel将es6语法转es5的简单示例
Dec 01 Javascript
bootstrap动态调用select下拉框的实例代码
Aug 09 Javascript
layui 中select下拉change事件失效的解决方法
Sep 20 Javascript
vue.js+ElementUI实现进度条提示密码强度效果
Jan 18 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
收集的DedeCMS一些使用经验
2007/03/17 PHP
Yii Framework框架获取分类下面的所有子类方法
2014/06/20 PHP
利用laravel+ajax实现文件上传功能方法示例
2017/08/13 PHP
自定义一个jquery插件[鼠标悬浮时候 出现说明label]
2011/06/27 Javascript
document.getElementById获取控件对象为空的解决方法
2013/11/20 Javascript
一款由jquery实现的整屏切换特效
2014/09/15 Javascript
javascript框架设计之类工厂
2015/06/23 Javascript
自己动手写的jquery分页控件(非常简单实用)
2015/10/28 Javascript
基于Bootstrap的Java开发问题汇总(Spring MVC)
2017/01/15 Javascript
JavaScript中动态向表格添加数据
2017/01/24 Javascript
JavaScript中正则表达式使数字、中文或指定字符高亮显示
2017/10/31 Javascript
解决bootstrap中下拉菜单点击后不关闭的问题
2018/08/10 Javascript
Angular2中监听数据更新的方法
2018/08/31 Javascript
Vue中控制v-for循环次数的实现方法
2018/09/26 Javascript
简单通过settimeout看javascript的运行机制
2019/05/10 Javascript
使用JavaScript通过前端发送电子邮件
2020/05/22 Javascript
带你使用webpack快速构建web项目的方法
2020/11/12 Javascript
[02:20]DOTA2亚洲邀请赛 EHOME战队出场宣传片
2015/02/07 DOTA
python选择排序算法的实现代码
2013/11/21 Python
简单讲解Python中的闭包
2015/08/11 Python
python用模块zlib压缩与解压字符串和文件的方法
2016/12/16 Python
python使用threading获取线程函数返回值的实现方法
2017/11/15 Python
python之matplotlib学习绘制动态更新图实例代码
2018/01/23 Python
给你一面国旗 教你用python画中国国旗
2019/09/24 Python
Numpy 理解ndarray对象的示例代码
2020/04/03 Python
解决python DataFrame 打印结果不换行问题
2020/04/09 Python
python解包概念及实例
2021/02/17 Python
英国购买威士忌网站:Master of Malt
2019/09/26 全球购物
Goodee官方商店:迷你投影仪
2021/03/15 全球购物
商务英语专业自荐信
2013/10/14 职场文书
工业设计专业推荐信
2013/10/29 职场文书
招商业务员岗位职责
2013/12/16 职场文书
继承公证书格式
2015/01/26 职场文书
2015年安全月活动总结
2015/03/26 职场文书
CSS中Single Div 绘图技巧的实现
2021/06/18 HTML / CSS
Java实现聊天机器人完善版
2021/07/04 Java/Android