后序非递归遍历:
后序非递归遍历和先序、中序非递归遍历主要的差别在于:当从子树返回时,如何判断该子树是从左子树返回的还是从右子树返回的,由此来确定栈顶元素的上一层结点是否应该出栈,因此,后序非递归遍历最主要的就是判断刚访问过的结点q是不是当前栈顶结点p的右孩子
(1)p没有右孩子,则表明此时应该访问根结点;
(2)p的右孩子是刚被访问过的结点q,此时也应该访问根结点(定义结点q的原因是标记被访问过的q结点)。
算法1:(1)从根结点开始,当前结点存在或者栈不为空,进入循环;
(2)当前结点进栈,并进入其左子树,一直循环直到左子树为空;
(3)如果此时栈非空,判断当前结点的右孩子是否为空或者是否被访问过,是,则退栈,输出p结点,p结点赋给q结点,p结点置空(此时置空p结点的原因是以免下次进入while循环);不是,则进入p的右子树。
void PostOrder(BiTree root)//后序
{
SeqStack *S;
BiTree p,q;
InitStack(&S);
p=root;
q=NULL;
while(p||!StackEmpty(S))
{
while(p!=NULL)
{
Push(S,p);
p=p->Lchild;
}
if(!StackEmpty(S))
{
Top(S,&p);
if((p->Rchild==NULL)||(p->Rchild==q))
{
Pop(S,&p);
printf("%c",p->data);
q=p;
p=NULL;
}
else
p=p->Rchild;
}
}
}
算法2:(1)从根结点开始,当前结点存在或者栈不为空,进入循环;
(2)当前结点不为空,进栈,并进入其左子树;
(3)若当前结点为空,则判断栈顶元素p的右子树是否为空或者右子树是否被访问过,是,则退栈,输出当前结点p,p赋给q,p置为空;不是,则进入当前结点p的右子树
void PostOrder(BiTree root)//后序
{
SeqStack *S;
BiTree p,q;
InitStack(&S);
p=root;
q=NULL;
while(p||!StackEmpty(S))
{
if(p)
{
Push(S,p);
p=p->Lchild;
}
else
{
Top(S,&p);
if(p->Rchild==NULL||p->Rchild==q)
{
Pop(S,&p);
printf("%c",p->data);
q=p;
p=NULL;
}
else
p=p->Rchild;
}
}
}
全部程序:
#include<stdio.h>
#include<stdlib.h>
#define MAXSIZE 100
typedef char DataType;
typedef struct Node
{
DataType data;
struct Node * Lchild;
struct Node * Rchild;
} BiTNode,*BiTree;
typedef BiTree DataType1;
typedef struct
{
DataType1 data1[MAXSIZE];
int top;
}SeqStack;
void InitStack(SeqStack **s)//置空栈
{
(*s)=(SeqStack *)malloc(sizeof(SeqStack));
(*s)->top=-1;
}
int StackEmpty(SeqStack *s)//判空栈
{
if(s->top==-1)
return 1;
else
return 0;
}
int Push(SeqStack *s,DataType1 x)//入栈
{
if(s->top==MAXSIZE-1)
return 0;
else
{
s->top++;
s->data1[s->top]=x;
return 1;
}
}
int Pop(SeqStack *s,DataType1 *x)//出栈
{
if(StackEmpty(s)) return 0;
else
{
*x=s->data1[s->top];
s->top--;
return 1;
}
}
int Top(SeqStack *s,DataType1 *x)//出栈顶元素
{
if(StackEmpty(s))
return 0;
else
{
*x=(s->data1[s->top]);
return 1;
}
}
void CreateBiTree(BiTree *root)
{
char ch;
ch=getchar();
if(ch=='^')
*root=NULL;
else
{
*root=(BiTree)malloc(sizeof(BiTNode));
(*root)->data=ch;
CreateBiTree(&((*root)->Lchild));
CreateBiTree(&((*root)->Rchild));
}
}
/*void PostOrder(BiTree root)//后序
{
SeqStack *S;
BiTree p,q;
InitStack(&S);
p=root;
q=NULL;
while(p||!StackEmpty(S))
{
while(p!=NULL)
{
Push(S,p);
p=p->Lchild;
}
if(!StackEmpty(S))
{
Top(S,&p);
if((p->Rchild==NULL)||(p->Rchild==q))
{
Pop(S,&p);
printf("%c",p->data);
q=p;
p=NULL;
}
else
p=p->Rchild;
}
}
}*/
void PostOrder(BiTree root)//后序
{
SeqStack *S;
BiTree p,q;
InitStack(&S);
p=root;
q=NULL;
while(p||!StackEmpty(S))
{
if(p)
{
Push(S,p);
p=p->Lchild;
}
else
{
Top(S,&p);
if(p->Rchild==NULL||p->Rchild==q)
{
Pop(S,&p);
printf("%c",p->data);
q=p;
p=NULL;
}
else
p=p->Rchild;
}
}
}
int main(void)
{
BiTree root;
root=(BiTree)malloc(sizeof(BiTNode));
CreateBiTree(&root);
PostOrder(root);
}