二叉树的非递归遍历
来源:互联网 发布:java http 上传文件 编辑:程序博客网 时间:2024/06/05 18:16
树的非递归遍历比递归遍历要复杂,用栈来保存节点。
typedef struct node{
Elemtype data;
struct node* lChild;
struct node* rChild;
}BTNode;
1.先序遍历非递归算法
思路:由先序遍历过程可知,先访问根节点,再访问左子树,最后访问右子树,因此,先将根节点进栈,在栈不空时循环:出栈p,访问*p节点,若右孩子不为空将该右孩子节点进栈,若左孩子不空,再将左孩子节点 进栈。
void PreOrder(BTNode* b){
BTNode* St[MaxSize],*p;
int top=-1;
if(b!=NULL){
top++; //根节点进栈
St[top]=b;
while(top>-1){ //栈不为空时循环
p=St[top]; //退栈并访问该节点
top--;
printf("%c",p->data);
if(p->rChild!=NULL){ //右孩子节点进栈
top++;
St[top]=p->rChild;
}
if(p->lChild){ //左孩子结点进栈
top++;
St[top]=p->lChild;
}
}
printf("\n");
}
}
2.中序遍历非递归算法
思路:用指针指向当前要处理的结点。先扫描(并非访问)根结点的所有左结点并将它们一一进栈,当无左结点时表示栈顶节点无左子树,然后出栈这个结点,并访问它,将p指向刚出栈结点的右孩子,对右孩子做同样的处理。需要注意的是,当结点*p的所有左下结点进栈后,这时的栈顶结点要么没有左子树,要么其左子树已经访问过,就可以访问这个栈顶结点。如此这样,直到栈空。
void InOrder(BTNode* b){
BTNode* St[MaxSize],*p;
int top=-1;
if(b!=NULL){
p=b;
while(top>-1||p!=NULL){ //处理*p结点的左子树
while(p!=NULL){ //扫描*p的所有左结点并进栈
top++;
St[top]=p;
p=p->lChild;
}
//执行到此处时,栈顶元素没有左孩子或者左子树均以被访问过
if(top>-1){
p=St[top]; //出栈*p结点
top--;
printf("%c",p->data); //访问之
p=p->rChild; //转向处理*p的右孩子结点
}
}
printf("\n")
}
}
3.后序遍历非递归算法
思路:采用一个栈保存需要返回的结点指针,先扫描根节点的所有左结点并一一进栈,出栈一个结点*b作为当前结点,然后扫描该结点的右子树。当一个结点的左右孩子均被访问后再访问该结点,直到栈空为止。难点是如何判断一个结点*b的右子树已经被访问过(实际上当*b结点的右孩子被访问过,那么其油子树就已经被访问过),为此用p保存刚刚访问过的结点,初值设为NULL,若b-rChild==p成立(在后序遍历中,*b的右孩子结点一定刚好在*b访问之前被访问),说明*b的左右孩子均已被访问,可以访问*b;
void PostOrder(BTNode* b){
BTNode* St[MaxSize];
BTNode* p;
int flag,top=-1;
if(b!=NULL)
do{
while{(b!=NULL) //将b的所有左结点入栈
{
top++;
St[top]=b;
b=b->lChild;
}
//执行到此处说明栈顶元素没有左孩子或者左子树已经被访问过
p=NULL; //p指向栈顶结点的前一个已访问的结点
flag=1; //表示*b的左孩子已经被访问过或者是空
while(top!=-1&&flag){
b=St[top]; //取出当前栈顶元素
if(b->rChild==p){
/* 若p=NULL表示b的右孩子不存在,而其左子树不在或已经被 访问,所以可以访问*b;若p不等于NULL,表示b的右子树已访问(原因是p指向b的右子树中刚访问过的结点,而*p是b的右子树中后序序列的最后一个结点),所以可以访问*b */
printf("%c",p->data); //访问*b结点
top--;
p=b; //p指向刚刚访问过的结点
}else{
b=b->rChild; //b指向右孩子结点
flag=0; //表示*b的左孩子尚未访问过
}
}
}while(top!=-1)
}
printf("\n");
}
}
- 二叉树的递归,非递归遍历
- 二叉树的递归+非递归遍历
- 二叉树的递归非递归遍历
- 二叉树的遍历--递归+非递归
- 二叉树的递归、非递归遍历
- 二叉树的递归非递归遍历
- 二叉树的先中后序遍历,递归遍历,非递归遍历
- 二叉树的递归遍历与非递归遍历
- 二叉树的创建,递归遍历,非递归遍历
- 二叉树的递归遍历与非递归遍历
- 二叉树的非递归遍历以及递归遍历
- 二叉树的非递归遍历&递归遍历
- 二叉树的递归遍历和非递归遍历
- 二叉树的递归遍历与非递归遍历
- 二叉树的递归遍历和非递归遍历
- 二叉树的构造,递归遍历,非递归遍历
- 二叉树的遍历(递归+非递归+层次遍历)
- 二叉树的递归遍历与非递归遍历
- 2015-4-26分享的PDF
- CI框架目录结构及运行机制
- OC笔记 - NSOperation(2015.4.25)
- 如何用U盘安装win7系统(通过命令行制作U盘启动盘)
- MIME_type类型语法
- 二叉树的非递归遍历
- JavaScript - 表单验证实例
- 部署Python+Selenium2自动化测试环境
- 批处理
- ZOJ 3878 Convert QWERTY to Dvorak (The 12th Zhejiang Provincial Collegiate Programming Contest)
- JavaScript - 正则表达式
- OC笔记 - POST、GET请求、数据加密(2015.4.25)
- [LeetCode]Sort List
- ZOJ 3870 Team Formation(浙江省第12届ACM省赛第二题)