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


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 相关文章推荐
JQuery 风格的HTML文本转义
Jul 01 Javascript
编写高效jQuery代码的4个原则和5个技巧
Apr 24 Javascript
Javascript的&&和||的另类用法
Jul 23 Javascript
JS实现图片产生波纹一样flash效果的方法
Feb 27 Javascript
javascript中hasOwnProperty() 方法使用指南
Mar 09 Javascript
jQuery实现带动画效果的多级下拉菜单代码
Sep 08 Javascript
将List对象列表转换成JSON格式的类实现方法
Jul 04 Javascript
JavaScript无操作后屏保功能的实现方法
Jul 04 Javascript
vue语法自动转typescript(解放双手)
Sep 18 Javascript
解决layui中onchange失效以及form动态渲染失效的问题
Sep 27 Javascript
微信小程序indexOf的替换方法(推荐)
Jan 14 Javascript
Vue切换Tab动态渲染组件的操作
Sep 21 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
PHP脚本中include文件出错解决方法
2008/11/20 PHP
PHP 作用域解析运算符(::)
2010/07/27 PHP
基于Discuz security.inc.php代码的深入分析
2013/06/03 PHP
ThinkPHP实现支付宝接口功能实例
2014/12/02 PHP
PHP简单实现遍历目录下特定文件的方法小结
2017/05/22 PHP
JavaScript 学习初步 入门教程
2010/03/25 Javascript
Javascript(AJAX)解析XML的代码(兼容FIREFOX/IE)
2010/07/11 Javascript
javascript中检测变量的类型的代码
2010/12/28 Javascript
jQuery快速上手:写jQuery与直接写JS的区别详细解析
2013/08/26 Javascript
javascript中数组中求最大值示例代码
2013/12/18 Javascript
Javascript动态创建div的方法
2015/02/09 Javascript
js实现div层缓慢收缩与展开的方法
2015/05/11 Javascript
JavaScript重载函数实例剖析
2016/05/13 Javascript
jQuery Easyui Datagrid实现单行的上移下移及保存移动的结果
2016/08/15 Javascript
js完整倒计时代码分享
2016/09/18 Javascript
js实现下拉框效果(select)
2017/03/28 Javascript
JavaScript脚本语言是什么_动力节点Java学院整理
2017/06/26 Javascript
jQuery:unbind方法的使用详解
2017/08/14 jQuery
微信小程序实现点击按钮修改文字大小功能【附demo源码下载】
2017/12/06 Javascript
浅谈gulp创建完整的项目流程
2017/12/20 Javascript
基于vue中css预加载使用sass的配置方式详解
2018/03/13 Javascript
vue项目关闭eslint校验
2018/03/21 Javascript
Vue使用vue-area-linkage实现地址三级联动效果的示例
2018/06/27 Javascript
js实现上传图片并显示图片名称
2019/12/18 Javascript
PyQt5基本控件使用之消息弹出、用户输入、文件对话框的使用方法
2019/08/06 Python
python使用nibabel和sitk读取保存nii.gz文件实例
2020/07/01 Python
Python中生成ndarray实例讲解
2021/02/22 Python
linux系统都有哪些运行级别
2016/03/26 面试题
教师找工作推荐信
2013/11/23 职场文书
毕业设计计划书
2014/01/09 职场文书
结婚喜宴家长答谢词
2014/01/15 职场文书
经典导游欢迎词大全
2014/01/16 职场文书
经销商订货会主持词
2014/03/27 职场文书
镇党委书记群众路线整改措施思想汇报
2014/10/13 职场文书
2014年初一班主任工作总结
2014/11/08 职场文书
大三学生英语考试作弊检讨书
2015/01/01 职场文书