中序遍历二叉树 非递归 非栈 用的是指针
2013-04-07 19:52
162 查看
有个二叉树,每个节点除了左右指针外,还有一个指向父节点的指针。
要求不用递归,中序遍历这棵树。另要求空间复杂度是O(1).
空间复杂度为O(1),摆明就是不让用堆栈模拟递归,所以想了想思路,也请教过好几个朋友,大家都基本想法都差不多,由于有指向父节点的指针,必定可以回溯,从而可以不需要堆栈来做记录.
view plain
/*思路:
关于终止条件:中序遍历终止于最后的rchild,只能先遍历一遍,将该节点作为终止条件。
对遍历时候的 cur节点设置一个状态(0,1,2)
0标识其左,右节点情况尚未处理
1标识其左节点被处理(包括左节点不存在的情况)
2标识从右节点返回(包括右节点不存在的情况)
3种状态的判断用(post->parent->lchild == post)这样的方法判断。
*/
void inorder_norecursive(LinkTree *root)
{
LinkTree * cur=root, * post, *fin;
int cur_state = 0;
while(cur != NULL) //查找终止条件
{
post = cur;
cur = cur->rchild;
}
fin = post;
cur = root;
post = NULL;
printf("fin data :%d /n",fin->data);
while( !(cur == fin && cur_state >=1) )
{
while(cur != NULL && cur->lchild != NULL && cur_state != 2) //搜索:每次遍历,当前状态清零,找到可以打印的点,从右节点返回不应该继续向下遍历
{
cur_state = 0;
cur = cur->lchild;
}
if( (cur == NULL && cur_state == 1) || cur_state == 2) //返回:右节点为空,返回的情况或者从右节点返回
{
cur = post;
if(cur->parent->lchild == cur)
cur_state = 1;
else if(cur->parent->rchild == cur)
cur_state = 2;
cur = cur->parent;
}
if( cur->lchild == NULL && cur_state == 0)
cur_state = 1;
post = cur; //post针对cur遍历到NULL时候返回,记录有效节点
if( cur_state == 1) //中序打印
{
printf(" %d ",cur->data);
if(cur == fin) //打印最后一个,显式退出
break;
}
else if(cur_state == 2) //节点的2个子节点已被处理,向上返回
continue;
if(cur->rchild == fin) //如果是fin节点的父节点,提前设置cur_state状态,防止while退出
cur_state = 0;
cur = cur->rchild;
}
}
要求不用递归,中序遍历这棵树。另要求空间复杂度是O(1).
空间复杂度为O(1),摆明就是不让用堆栈模拟递归,所以想了想思路,也请教过好几个朋友,大家都基本想法都差不多,由于有指向父节点的指针,必定可以回溯,从而可以不需要堆栈来做记录.
view plain
/*思路:
关于终止条件:中序遍历终止于最后的rchild,只能先遍历一遍,将该节点作为终止条件。
对遍历时候的 cur节点设置一个状态(0,1,2)
0标识其左,右节点情况尚未处理
1标识其左节点被处理(包括左节点不存在的情况)
2标识从右节点返回(包括右节点不存在的情况)
3种状态的判断用(post->parent->lchild == post)这样的方法判断。
*/
void inorder_norecursive(LinkTree *root)
{
LinkTree * cur=root, * post, *fin;
int cur_state = 0;
while(cur != NULL) //查找终止条件
{
post = cur;
cur = cur->rchild;
}
fin = post;
cur = root;
post = NULL;
printf("fin data :%d /n",fin->data);
while( !(cur == fin && cur_state >=1) )
{
while(cur != NULL && cur->lchild != NULL && cur_state != 2) //搜索:每次遍历,当前状态清零,找到可以打印的点,从右节点返回不应该继续向下遍历
{
cur_state = 0;
cur = cur->lchild;
}
if( (cur == NULL && cur_state == 1) || cur_state == 2) //返回:右节点为空,返回的情况或者从右节点返回
{
cur = post;
if(cur->parent->lchild == cur)
cur_state = 1;
else if(cur->parent->rchild == cur)
cur_state = 2;
cur = cur->parent;
}
if( cur->lchild == NULL && cur_state == 0)
cur_state = 1;
post = cur; //post针对cur遍历到NULL时候返回,记录有效节点
if( cur_state == 1) //中序打印
{
printf(" %d ",cur->data);
if(cur == fin) //打印最后一个,显式退出
break;
}
else if(cur_state == 2) //节点的2个子节点已被处理,向上返回
continue;
if(cur->rchild == fin) //如果是fin节点的父节点,提前设置cur_state状态,防止while退出
cur_state = 0;
cur = cur->rchild;
}
}
相关文章推荐
- 输入完全二叉树的先序序列,用#代表虚结点(空指针),如ABD###CE##F##,建立二叉树的二叉链表。 (2)写出对用二叉链表存储的二叉树进行先序、中序和后序遍历的递归和非递归算法。 (3)写出
- 二叉树构建,先序,中序,后序遍历(以及非递归实现),广度优先遍历
- c语言实现二叉树先序,中序,后序(递归),层次遍历,求叶子节点个数及树的深度,下一篇写非递归的遍历
- 二叉树的遍历:前序,中序,后序,层序--包括递归和非递归实现
- 用递归方法对二叉树进行先序、中序和后序遍历
- 二叉树(前序,中序,后序,层序)遍历递归与循环的python实现
- (编程训练)再回首,数据结构——二叉树的前序、中序、后序遍历(非递归)
- 树及树的遍历(二)-----二叉树前序、中序、后序遍历非递归写法的透彻解析
- 二叉树 前序、中序、后序、层次遍历及非递归实现 查找、统计个数、比较、求深度的递归实现
- 数据结构二叉树——建立二叉树、中序递归遍历、非递归遍历、层次遍历
- (1)建立二叉树的二叉链表。 (2)写出对用二叉链表存储的二叉树进行先序、中序和后序遍历的递归和非递归算法。 (3)写出对用二叉链表存储的二叉树进行层次遍历算法。 (4)求二叉树的所有叶子及结点总数。
- 二叉树的中序非递归遍历c++版
- 二叉树的深度优先dfs遍历(前序、中序和后序;递归与非递归)
- 二叉树非递归和递归遍历(先序,中序,后序)
- 二叉树 前序、中序、后序、层次遍历及非递归实现 查找、统计个数、比较、求深度的递归实现
- 二叉树的创建 先序 中序 后续 递归和非递归遍历
- 二叉树的前序,中序,后序遍历(递归非递归实现)
- 用递归方法对二叉树进行先序、中序和后序遍历
- 中序非递归遍历二叉树
- JAVA下实现二叉树的先序、中序、后序、层序遍历(递归和循环)