二叉树(五)-----后序非递归遍历

后序非递归遍历:

后序非递归遍历和先序、中序非递归遍历主要的差别在于:当从子树返回时,如何判断该子树是从左子树返回的还是从右子树返回的,由此来确定栈顶元素的上一层结点是否应该出栈,因此,后序非递归遍历最主要的就是判断刚访问过的结点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);
}




猜你喜欢

转载自blog.csdn.net/wangkeke1996/article/details/79180688