树的先序、中序、后序遍历非递归实现
来源:互联网 发布:云计算和超级计算机 编辑:程序博客网 时间:2024/04/30 21:20
1. 树的后序遍历
对照《将递归函数转换为非递归形式》的“5. 去掉goto后优化的非递归实现步骤”,可以实现树的后序遍历非递归函数:
enum Tags{ROOT,LEFT,RIGHT}; //Tags对应《将递归函数转换为非递归形式》提到的rdtemplate<typename Comparable>class ELEM{public: typename BinarySearchTree<Comparable>::_BinaryNode* point; Tags tag;};template<typename Comparable>void BinarySearchTree<Comparable>::postOrderTraverStack(BinaryNode* t)const{ std::stack<ELEM<Comparable> > s; ELEM<Comparable> element,tmp; tmp.point = t; tmp.tag = ROOT; s.push(tmp); // 步骤(1):对根节点压栈 do { while( (element = s.top()).point != NULL) //步骤(2):对根节点不断向下搜索,直到满足递归出口条件。这里的出口条件为:element.pointer = NULL { tmp.point = element.point->left; tmp.tag = LEFT; s.push(tmp); } //因为对于出口条件element.point == NULL,不需要做任何操作,所以步骤(3)省略 while( (element = s.top()).tag == RIGHT) //步骤(4):如果当前节点是父节点最后一个节点,则不断上溯,直到找到不是父节点最后一个节点的祖先节点 { s.pop(); element = s.top(); (element.point)->visit(); } if( (element = s.top()).tag == LEFT) //步骤(5):如果当前节点不是父节点最后一个节点,把兄弟节点压栈 { s.pop(); element = s.top(); tmp.point = element.point->right; tmp.tag = RIGHT; s.push(tmp); } }while( (element = s.top()).tag != ROOT); //步骤(4)上溯的过程可能到达根节点。 s.pop();}
2. 树的先序遍历、中序遍历简化处理
我们同样也可以严格按照上面的步骤写出先序遍历和中序遍历的非递归函数。不过由于先序遍历和中序遍历递归函数调用了最后一个递归子函数(右节点)后不需要再对当前函数进行相关处理,也就是说左节点处理完后,可以将左节点和父节点先从堆栈中删除,然后再对右节点入栈,这样右节点就占据了父节点的位置。具体见下面两幅图,图2将图1的C1、 D1删除只剩下D2,这时相当于D2占据了父节点C1的位置,由于C1是B1的左节点,所以将C1、 D1删除后新压入栈的D2一定是它的新回溯节点B1的左节点。所以就不用再考虑步骤(4)了。从而简化了递归到非递归的转换过程。
3. 先序遍历非递归代码:
template<typename Comparable>void BinarySearchTree<Comparable>::preOrderTraverStack(BinaryNode* t)const{ std::stack<BinaryNode*> s; s.push(t); BinaryNode* p = NULL; //步骤(1):对根节点压栈 while(!s.empty()) { while( (p = s.top()) != NULL) //步骤(2):不断遍历左节点,直到空(空为递归出口) { p->visit(); //访问当前节点 s.push(p->left); } //后面分两种情况:栈顶节点或为左节点或为根节点。 s.pop(); //空节点不需要做任何事情仅pop掉即可 if(!s.empty()) //若之前的栈顶节点是根节点这里栈空,函数结束;若为左节点,后面的语句进行步骤(5)处理 { //步骤(5):处理当前节点不是父节点最后一个节点即为左节点的情况 p = s.top(); s.pop(); //**右节点入栈前先删除父节点** s.push(p->right); } } }
4. 中序遍历非递归代码:
template<typename Comparable>void BinarySearchTree<Comparable>::inOrderTraverStack(BinaryNode* t)const{ std::stack<BinaryNode*> s; s.push(t); BinaryNode* p = NULL; while(!s.empty()) { while( (p = s.top()) != NULL) { s.push(p->left); } s.pop(); if(!s.empty()) { p = s.top(); p->visit(); s.pop(); s.push(p->right); } }}
5. 参考
《 将递归函数转换为非递归形式》
0 0
- 二叉树的先序、中序、后序遍历的递归和非递归实现
- 非递归算法实现树的先序遍历,中序遍历,后序遍历;也有树的层次遍历。
- 二叉树的先序、中序、后序遍历的非递归实现
- 二叉树遍历的非递归算法(先序、中序、后序)代码实现
- 树的先序、中序、后序遍历非递归实现
- c语言原生实现二叉树的 非递归 中序 先序 后序 遍历
- C++实现二叉树的递归遍历与非递归遍历(先序、中序、后序、层序)
- 二叉树的先序、中序、后序递归遍历和非递归遍历
- 二叉树的创建(先序创建的)及先序遍历 中序遍历 后序遍历的递归和非递归实现
- [转载]树的先序遍历,中序遍历,后序遍历的非递归写法
- 二叉树的先序、中序、后序的递归及非递归实现,以及层次遍历的实现:
- 再回首,数据结构——树的先序、中序、后序遍历的递归与非递归实现
- java 实现二叉树的构建,先序,中序,后序,层次,递归,非递归的遍历
- 递归和非递归的方式实现二叉树的先序、中序和后序遍历
- 建立二叉树,实现二叉树的先序遍历、中序和后序遍历的非递归算法
- 二叉树的递归 非递归 先序 中序 后序及层次遍历代码实现
- 分别用递归和非递归方式实现二叉树的先序、中序和后序遍历
- 二叉树的建树、遍历(先序、中序、后序、层次)(递归和非递归)--Java实现
- Leetcode #64 Minimum Path Sum
- 模式6-替代模板方式模式
- VIM 编辑器
- 测试server是否block port或者网站
- hdu 2399 GPA
- 树的先序、中序、后序遍历非递归实现
- 在eclipse下配置maven
- 本地自旋锁与信号量/多服务台自旋队列-spin wait风格的信号量
- associative
- hdu 1328 IBM Minus One
- 【LeetCode-面试算法经典-Java实现】【038-Count and Say(计数和表述)】
- 【LeetCode-面试算法经典-Java实现】【046-Permutations(求排列)】
- Linux jdk安装与卸载
- 【LeetCode-面试算法经典-Java实现】【050-Implement pow(x, n)(求x的n次方)】