二叉树遍历方法总结
来源:互联网 发布:增肌粉蛋白粉区别知乎 编辑:程序博客网 时间:2024/06/06 18:44
一、递归方法
1、前序遍历 : 根——左——右
Preorder_tree_walk(x){ //x为根节点
if x != nil
print x.key;
preorder_tree_walk(x.left);
Preorder_tree_walk(x.right);
}
2、中序遍历 : 左——根——右
Inorder_tree_walk(x){
if x!=nil
Inorder_tree_walk(x.left);
print x.key;
Inorder_tree_walk(x.right);
}
3、后序遍历 : 左——右——根
Postorder_tree_walk(x){
if x!=nil
Postorder_tree_walk(x.left);
Postorder_tree_walk(x.right);
print x.key;
}
二、非递归方法
比较难的是非递归方法,可以有多种方法实现。
1、前序遍历
a、第一种方法,这也是我未参考别人而写出来的,把根节点压入栈,然后若栈不为空则循环,弹出并打印出栈顶元素,压入两个孩子节点(如果有的话),再继续循环,直到栈为空
Preorder_tree_walk(x){
stack S;
push(S,x);
while(S.top != null){
x=pop(S);
print x.key;
if x.left != null
push(S,x.left);
if x.right != null
push(S.x.right);
}
}
b、第二种,也是标准的算法,
处理过程如下:
1>内层while循环:对任一节点x,如果x不为null,访问x,并把x压入栈,再令x等于x的左孩子节点,循环1,直到x为null;
2>如果栈顶不为空,弹出栈顶元素x,并令x为x的有孩子节点,返回1>,继续执行,直到栈为空且x为Null.
Preorder_tree_walk(x){
stack S;
while(x!=null || S.top != null){
while(x!=null){
print x.key;
push(S,x);
x=x.left;
}
if(S.top!=null){
x=pop(S);
x=x.right;
}
}
}
2、中序遍历:据中序遍历的顺序,先左孩子,再根节点,再右孩子。
1>如图第一个红色箭头所示,依次将当前节点及其所有左后代元素压入栈(图中1,2,3),直到左孩子为空,
2>将栈顶元素x弹出并打印,把x的右孩子作为当前节点,返回1>执行;
Inorder_tree_walk(x){
stack S;
while(x!=null || S.top!=null){
while(x!=null){
push(S,x);
x=x.left;
}
if(S.top!=null){
x=pop(S);
print x.key;
x=x.right;
}
}
}
3、后序遍历:次序为左——右——根
a、第一种方法:
1>沿左子树一直往下走,并依次压入栈,直到左孩子节点为空,此时不能将栈顶元素出栈,因为右子树还没有遍历,
2>如果栈顶元素curr右孩子为空或者右孩子已访问,则输出栈顶元素,并置栈顶元素为prev上一个访问节点,
否则,置当前元素curr为栈顶元素右孩子,返回1>执行,当其右孩子访问完时,该节点又出现在栈顶,此时该节点可以出栈。
可以看出,在这个过程中,每个结点都两次出现在栈顶,只有在第二次出现在栈顶时,才能访问它。因此需要多设置一个变量标识该结点是否是第一次出现在栈顶。
Postorder_tree_walk(curr){
stack S;
prev=null;//上一次访问节点
while(curr!=null || S.top!=null){
while(curr!=null){ //一直向左走,并压入栈,直到左孩子为空
push(S,curr);
curr=curr.left;
}
curr=S.top;
if(curr.right==null || curr.right==prev){ //如果当前元素右孩子为空或者右孩子已访问,则访问当前节点
print curr.key;
prev = curr;
pop(S);
curr=null;
}
else curr=curr.right;//否则访问右孩子
}
}
b、第二种方法
要保证根结点在左孩子和右孩子访问之后才能访问,因此对于任一结点P,先将其入栈。如果P不存在左孩子和右孩子,则可以直接访问它;或者P存在左孩子或者右孩子,但是其左孩子和右孩子都已被访问过了,则同样可以直接访问该结点。若非上述两种情况,则将P的右孩子和左孩子依次入栈,这样就保证了每次取栈顶元素的时候,左孩子在右孩子前面被访问,左孩子和右孩子都在根结点前面被访问。
Postorder_tree_walk(x){
stack S;
curr; //当前节点
prev=null;//上一个访问节点
push(S,x);
while(S.top!=null){
curr=S.top;
if((curr.left==null &&curr.right==null) ||
(prev!=null && (prev==curr.left||prev==curr.right))){
print curr.key;
pop(S);
prev=curr;
}
else {
if(curr.left!=null)
push(S,curr.left);
if(curr.right!=null)
push(S,curr.right);
}
}
}
参考资料:
1>http://blog.csdn.net/hackbuteer1/article/details/6583988
2>http://www.cnblogs.com/dolphin0520/archive/2011/08/25/2153720.html
- 二叉树遍历方法总结
- 二叉树非递归遍历方法总结
- 二叉树遍历总结
- 二叉树遍历方法
- 二叉树遍历方法
- Binary Tree Traversal二叉树遍历方法总结
- 二叉树 遍历 算法总结
- 二叉树遍历 推倒总结
- 二叉树遍历 推导总结
- 二叉树总结创建,遍历
- 二叉树遍历算法总结
- 二叉树遍历方式总结
- 二叉树遍历算法总结
- 二叉树的遍历总结
- 数据结构总结 & 二叉树遍历
- 数据结构-二叉树遍历总结
- 二叉树的遍历方法
- 二叉树遍历方法小结
- Android Support 22.1 发布!
- CSS兼容解决方法
- 练习7: 用递归法求斐波纳契数列的第n项, 体验编程之美
- spellChecker原理分析
- AOP之基于Schema配置总结与案例
- 二叉树遍历方法总结
- C 语言迭代求阶乘问题
- 【自用】有上下界的网络流
- 创建和销毁过程几个函数的执行顺序
- ios tintColor 与backgroundColor区别研究
- DOS命令下获取远程主机MAC地址的三种方法
- redhat/centos yum安装 This system is not registered with RHN
- 整体二分入门
- Ios UILabel 自适应 文本高度