昨天写数据结构关于二叉树的几种顺序的递归及非递归遍历的程序,后续遍历有点难。现在把程序给大家参考一下,有些思路参考自:的思路。

一、先序遍历二叉树

   1.递归遍历

    每次先判断是否为空树,若不是则访问根节点,然后左子树,最后右子树。

void PreOrderTraverse1(BiTree T) 
{//先序遍历二叉树T的递归算法 
//	cout<<"二叉树先序递归遍历\n";
	if(T)                                 //若二叉树非空 
	{
		cout<<T->data;                     //访问根节点 
		PreOrderTraverse1(T->lchild);        //遍历左孩子 
		PreOrderTraverse1(T->rchild);      //遍历右孩子 
	}}

二叉树后序遍历非递归java 二叉树后续遍历 非递归_二叉树后序遍历非递归java

  2.非递归遍历

   判断栈是否为空或子树为空,若不为空,就访问左孩子入栈,直至左孩子为空,若左孩子为空,就出栈,然后访问右孩子,入栈,就这样不断的循环。

二叉树后序遍历非递归java 二叉树后续遍历 非递归_二叉树后序遍历非递归java

void PreOrderTraverse2(BiTNode *T)
{//先序遍历二叉树T的非递归算法 
//	cout<<"二叉树先序非递归遍历\n";
	StackNode *S;
	BiTNode *p;
	S=NULL; 
	S=InitStack(S);
	p=T;

//	cout<<"pre1.1\n";
	if(p==NULL)
	{
//		cout<<"pre1.2\n";
		cout<<"树为空\n";
		return;
	}
//	cout<<"pre1.3\n";
	while(p||!StackEmpty(S))
	{

//		cout<<"pre1.4\n";
		if(p)
		{
//			cout<<"pre1.5\n";
			Push(S,p);
			cout<<p->data; 
			p=p->lchild;
		}
		else
		{
//			cout<<"pre1.6\n";
			Pop(S,p);
			p=p->rchild;	
		}
	}
//	cout<<"pre1.7\n";
}

二叉树后序遍历非递归java 二叉树后续遍历 非递归_二叉树后序遍历非递归java

 

二、中序遍历二叉树

     1.递归遍历

      每次先判断树是否为空,若不为空,则访问左子树,然后根子树,最后右子树。

二叉树后序遍历非递归java 二叉树后续遍历 非递归_二叉树后序遍历非递归java

void InOrderTraverse1(BiTree T) 
{//中序遍历二叉树T的递归算法 
//	cout<<"二叉树中序递归遍历\n";
	if(T)                                 //若二叉树非空 
	{
		InOrderTraverse1(T->lchild);        //遍历左孩子 
		cout<<T->data;                     //访问根节点 
		InOrderTraverse1(T->rchild);          //遍历右孩子 
	}}

二叉树后序遍历非递归java 二叉树后续遍历 非递归_二叉树后序遍历非递归java

    2.非递归遍历

    思路基本和先序差不多,只是输出数据的时候不一样。判断栈和树是否为空,若不,则判断树是否为空,不为继续将左子树进栈,若为空,则出栈,输出数据,然后访问右子树。

二叉树后序遍历非递归java 二叉树后续遍历 非递归_二叉树后序遍历非递归java

void InOrderTraverse2(BiTree &T)
{//中序遍历二叉树T的非递归算法 
//	cout<<"二叉树中序非递归遍历\n";
	StackNode *S;
	BiTNode *p;
	S=InitStack(S);
	p=T;
	while(p||!StackEmpty(S))
	{
		if(p)
		{			
			Push(S,p);
			p=p->lchild;
		}
		else
		{
			Pop(S,p);
			cout<<p->data;
			p=p->rchild;	
		}
	}
}

二叉树后序遍历非递归java 二叉树后续遍历 非递归_二叉树后序遍历非递归java

三、后序遍历二叉树

    1.递归遍历

    先判断树是否为空,若不为,先左子树,后右子树,然后根节点。

二叉树后序遍历非递归java 二叉树后续遍历 非递归_二叉树后序遍历非递归java

void LastOrderTraverse1(BiTree T) 
{//后序遍历二叉树T的递归算法
//	cout<<"二叉树后序递归遍历\n";
	if(T)                                 //若二叉树非空 
	{
		LastOrderTraverse1(T->lchild);        //遍历左孩子 
		LastOrderTraverse1(T->rchild);          //遍历右孩子 
		cout<<T->data;                     //访问根节点 
	}}

二叉树后序遍历非递归java 二叉树后续遍历 非递归_二叉树后序遍历非递归java

    2.非递归遍历

     要保证根结点在左孩子和右孩子访问之后才能访问,因此对于任一结点P,先将其入栈。如果P不存在左孩子和右孩子,则可以直接访问它;或者P存在左孩子或者右孩子,但是其左孩子和右孩子都已被访问过了,则同样可以直接访问该结点。若非上述两种情况,则将P的右孩子和左孩子依次入栈,这样就保证了每次取栈顶元素的时候,左孩子在右孩子前面被访问,左孩子和右孩子都在根结点前面被访问。

二叉树后序遍历非递归java 二叉树后续遍历 非递归_二叉树后序遍历非递归java

void LastOrderTraverse2(BiTNode *T)
{//后序遍历二叉树T的非递归算法 
//	cout<<"二叉树后序非递归遍历\n";
	StackNode *S;
	BiTNode *p,*cur;
	S=InitStack(S);
	p=T;
	p=NULL;cur=NULL;
	Push(S,T);
	while(!StackEmpty(S))
	{
		cur=NULL;
		GetTop(S,cur);
		if((cur->lchild==NULL && cur->rchild==NULL) || (p!=NULL &&(p==cur->lchild || p==cur->rchild)))
		{
			cout<<cur->data;
			p=cur;
			Pop(S,cur);

		}
		else
		{
			if(cur->rchild!=NULL)
			{
				Push(S,cur->rchild);
			 } 
			if(cur->lchild!=NULL)
			{
				Push(S,cur->lchild);
			 } 
		}
	}
}

二叉树后序遍历非递归java 二叉树后续遍历 非递归_二叉树后序遍历非递归java

 

 

下面是完整的程序:

#include<stdio.h>
#include<stdlib.h> 
#include<iostream>
using namespace std;typedef struct BiTNode             //树的结点 
{
	char data;  //节点数据域
	struct BiTNode *lchild,*rchild;     //左右孩子指针 
}BiTNode,*BiTree;typedef BiTNode *SElemType;
typedef struct StackNode           //栈的结点 
{
	SElemType data;
	StackNode *next;
}StackNode;StackNode *InitStack(StackNode *S)
{
	S=(StackNode *)malloc(sizeof(StackNode));
	if(S==NULL)
	{
		cout<<"内存不足,不能分配栈\n";
		exit(0);
	}
	S->next=NULL;
	return(S);
}int StackEmpty(StackNode *S) 
{
	if(S->next==NULL)
	{
		return(1);
	}
		return(0);	
}void Push(StackNode *S,SElemType data)
{
	StackNode *p;
	p = (StackNode *)malloc(sizeof(StackNode));
	if(p==NULL)
	{
		cout<<"内存不足,不能分配栈\n";
		exit(0);
	}
	p->data=data;
	p->next=S->next;
	S->next=p;

}void Pop(StackNode *S,SElemType &data)
{
	StackNode *p; 
	if(S->next==NULL)
	{
		cout<<"栈为空,无返回值\n";
	}
	p=S->next;
	data=p->data;
	S->next=p->next;
	free(p);

}int GetTop(StackNode *S,SElemType &data)
{
	if(S->next!=NULL)
	{
		data=S->next->data;
		return(1);
	}
	else
	{
		return(0);
	}
} 
BiTNode *InitTree(BiTNode *T)
{
	char data;
	cin>>data;
	if('#'==data)
	{
		T=NULL;
	}
	else
	{
		T=(BiTNode *)malloc(sizeof(BiTNode));
		T->data=data;
		T->lchild=InitTree(T->lchild);
		T->rchild=InitTree(T->rchild);

	}
	return(T);
}void PreOrderTraverse1(BiTree T) 
{//先序遍历二叉树T的递归算法 
//	cout<<"二叉树先序递归遍历\n";
	if(T)                                 //若二叉树非空 
	{
		cout<<T->data;                     //访问根节点 
		PreOrderTraverse1(T->lchild);        //遍历左孩子 
		PreOrderTraverse1(T->rchild);      //遍历右孩子 
	}}
void InOrderTraverse1(BiTree T) 
{//中序遍历二叉树T的递归算法 
//	cout<<"二叉树中序递归遍历\n";
	if(T)                                 //若二叉树非空 
	{
		InOrderTraverse1(T->lchild);        //遍历左孩子 
		cout<<T->data;                     //访问根节点 
		InOrderTraverse1(T->rchild);          //遍历右孩子 
	}}
void LastOrderTraverse1(BiTree T) 
{//后序遍历二叉树T的递归算法
//	cout<<"二叉树后序递归遍历\n";
	if(T)                                 //若二叉树非空 
	{
		LastOrderTraverse1(T->lchild);        //遍历左孩子 
		LastOrderTraverse1(T->rchild);          //遍历右孩子 
		cout<<T->data;                     //访问根节点 
	}}
void PreOrderTraverse2(BiTNode *T)
{//先序遍历二叉树T的非递归算法 
//	cout<<"二叉树先序非递归遍历\n";
	StackNode *S;
	BiTNode *p;
	S=NULL; 
	S=InitStack(S);
	p=T;

//	cout<<"pre1.1\n";
	if(p==NULL)
	{
//		cout<<"pre1.2\n";
		cout<<"树为空\n";
		return;
	}
//	cout<<"pre1.3\n";
	while(p||!StackEmpty(S))
	{

//		cout<<"pre1.4\n";
		if(p)
		{
//			cout<<"pre1.5\n";
			Push(S,p);
			cout<<p->data; 
			p=p->lchild;
		}
		else
		{
//			cout<<"pre1.6\n";
			Pop(S,p);
			p=p->rchild;	
		}
	}
//	cout<<"pre1.7\n";
} 
void InOrderTraverse2(BiTree &T)
{//中序遍历二叉树T的非递归算法 
//	cout<<"二叉树中序非递归遍历\n";
	StackNode *S;
	BiTNode *p;
	S=InitStack(S);
	p=T;
	while(p||!StackEmpty(S))
	{
		if(p)
		{			
			Push(S,p);
			p=p->lchild;
		}
		else
		{
			Pop(S,p);
			cout<<p->data;
			p=p->rchild;	
		}
	}
}void LastOrderTraverse2(BiTNode *T)
{//后序遍历二叉树T的非递归算法 
//	cout<<"二叉树后序非递归遍历\n";
	StackNode *S;
	BiTNode *p,*cur;
	S=InitStack(S);
	p=T;
	p=NULL;cur=NULL;
	Push(S,T);
	while(!StackEmpty(S))
	{
		cur=NULL;
		GetTop(S,cur);
		if((cur->lchild==NULL && cur->rchild==NULL) || (p!=NULL &&(p==cur->lchild || p==cur->rchild)))
		{
			cout<<cur->data;
			p=cur;
			Pop(S,cur);

		}
		else
		{
			if(cur->rchild!=NULL)
			{
				Push(S,cur->rchild);
			 } 
			if(cur->lchild!=NULL)
			{
				Push(S,cur->lchild);
			 } 
		}
	}
} 
int main()
{
	BiTNode *Tree;
	Tree=NULL;
	cout<<"按照层次遍历建立树,'#'表示树为空\n" <<endl; 
	cout<<"请输入要建立的树:"<<endl;
	cout<<"\n";
	Tree=InitTree(Tree);
	int choose;
	cout<<"请输入0(表示递归遍历)或1(表示非递归遍历)\n"; 
	cin>>choose;
	if(choose==0)
	{
		cout<<"二叉树先序递归遍历\n";	
		PreOrderTraverse1(Tree);
		cout<<endl; 
		cout<<"二叉树中序递归遍历\n";	
		InOrderTraverse1(Tree);	
		cout<<endl; 
		cout<<"二叉树后序递归遍历\n";
		LastOrderTraverse1(Tree);	
		cout<<endl; 
	}	
	else if(choose==1)
	{
		cout<<"二叉树先序非递归遍历\n";
		PreOrderTraverse2(Tree);
		cout<<endl; 	
		cout<<"二叉树中序非递归遍历\n";
		InOrderTraverse2(Tree);	
		cout<<endl; 
		cout<<"二叉树后序非递归遍历\n";
		LastOrderTraverse2(Tree);
		cout<<endl; 	
	}
	else
	{
		cout<<"输入错误\n"<<endl;
	}
	return 0;
}