二叉树的非递归遍历

来源:互联网 发布: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");

}

}

0 0
原创粉丝点击