昨天写数据结构关于二叉树的几种顺序的递归及非递归遍历的程序,后续遍历有点难。现在把程序给大家参考一下,有些思路参考自:http://www.cnblogs.com/dolphin0520/archive/2011/08/25/2153720.html的思路。
一、先序遍历二叉树
1.递归遍历
每次先判断是否为空树,若不是则访问根节点,然后左子树,最后右子树。
2.非递归遍历
判断栈是否为空或子树为空,若不为空,就访问左孩子入栈,直至左孩子为空,若左孩子为空,就出栈,然后访问右孩子,入栈,就这样不断的循环。
void PreOrderTraverse2(BiTNode *T)
{//先序遍历二叉树T的非递归算法
// cout<<"二叉树先序非递归遍历
";
StackNode *S;
BiTNode *p;
S=NULL;
S=InitStack(S);
p=T;
// cout<<"pre1.1
";
if(p==NULL)
{
// cout<<"pre1.2
";
cout<<"树为空
";
return;
}
// cout<<"pre1.3
";
while(p||!StackEmpty(S))
{
// cout<<"pre1.4
";
if(p)
{
// cout<<"pre1.5
";
Push(S,p);
cout<<p->data;
p=p->lchild;
}
else
{
// cout<<"pre1.6
";
Pop(S,p);
p=p->rchild;
}
}
// cout<<"pre1.7
";
}
二、中序遍历二叉树
1.递归遍历
每次先判断树是否为空,若不为空,则访问左子树,然后根子树,最后右子树。
void InOrderTraverse1(BiTree T)
{//中序遍历二叉树T的递归算法
// cout<<"二叉树中序递归遍历
";
if(T) //若二叉树非空
{
InOrderTraverse1(T->lchild); //遍历左孩子
cout<<T->data; //访问根节点
InOrderTraverse1(T->rchild); //遍历右孩子
}
}
2.非递归遍历
思路基本和先序差不多,只是输出数据的时候不一样。判断栈和树是否为空,若不,则判断树是否为空,不为继续将左子树进栈,若为空,则出栈,输出数据,然后访问右子树。
void InOrderTraverse2(BiTree &T)
{//中序遍历二叉树T的非递归算法
// cout<<"二叉树中序非递归遍历
";
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;
}
}
}
三、后序遍历二叉树
1.递归遍历
先判断树是否为空,若不为,先左子树,后右子树,然后根节点。
void LastOrderTraverse1(BiTree T)
{//后序遍历二叉树T的递归算法
// cout<<"二叉树后序递归遍历
";
if(T) //若二叉树非空
{
LastOrderTraverse1(T->lchild); //遍历左孩子
LastOrderTraverse1(T->rchild); //遍历右孩子
cout<<T->data; //访问根节点
}
}
2.非递归遍历
要保证根结点在左孩子和右孩子访问之后才能访问,因此对于任一结点P,先将其入栈。如果P不存在左孩子和右孩子,则可以直接访问它;或者P存在左孩子或者右孩子,但是其左孩子和右孩子都已被访问过了,则同样可以直接访问该结点。若非上述两种情况,则将P的右孩子和左孩子依次入栈,这样就保证了每次取栈顶元素的时候,左孩子在右孩子前面被访问,左孩子和右孩子都在根结点前面被访问。
void LastOrderTraverse2(BiTNode *T)
{//后序遍历二叉树T的非递归算法
// cout<<"二叉树后序非递归遍历
";
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);
}
}
}
}
下面是完整的程序:
#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<<"内存不足,不能分配栈
";
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<<"内存不足,不能分配栈
";
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<<"栈为空,无返回值
";
}
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<<"二叉树先序递归遍历
";
if(T) //若二叉树非空
{
cout<<T->data; //访问根节点
PreOrderTraverse1(T->lchild); //遍历左孩子
PreOrderTraverse1(T->rchild); //遍历右孩子
}
}
void InOrderTraverse1(BiTree T)
{//中序遍历二叉树T的递归算法
// cout<<"二叉树中序递归遍历
";
if(T) //若二叉树非空
{
InOrderTraverse1(T->lchild); //遍历左孩子
cout<<T->data; //访问根节点
InOrderTraverse1(T->rchild); //遍历右孩子
}
}
void LastOrderTraverse1(BiTree T)
{//后序遍历二叉树T的递归算法
// cout<<"二叉树后序递归遍历
";
if(T) //若二叉树非空
{
LastOrderTraverse1(T->lchild); //遍历左孩子
LastOrderTraverse1(T->rchild); //遍历右孩子
cout<<T->data; //访问根节点
}
}
void PreOrderTraverse2(BiTNode *T)
{//先序遍历二叉树T的非递归算法
// cout<<"二叉树先序非递归遍历
";
StackNode *S;
BiTNode *p;
S=NULL;
S=InitStack(S);
p=T;
// cout<<"pre1.1
";
if(p==NULL)
{
// cout<<"pre1.2
";
cout<<"树为空
";
return;
}
// cout<<"pre1.3
";
while(p||!StackEmpty(S))
{
// cout<<"pre1.4
";
if(p)
{
// cout<<"pre1.5
";
Push(S,p);
cout<<p->data;
p=p->lchild;
}
else
{
// cout<<"pre1.6
";
Pop(S,p);
p=p->rchild;
}
}
// cout<<"pre1.7
";
}
void InOrderTraverse2(BiTree &T)
{//中序遍历二叉树T的非递归算法
// cout<<"二叉树中序非递归遍历
";
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<<"二叉树后序非递归遍历
";
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<<"按照层次遍历建立树,'#'表示树为空
" <<endl;
cout<<"请输入要建立的树:"<<endl;
cout<<"
";
Tree=InitTree(Tree);
int choose;
cout<<"请输入0(表示递归遍历)或1(表示非递归遍历)
";
cin>>choose;
if(choose==0)
{
cout<<"二叉树先序递归遍历
";
PreOrderTraverse1(Tree);
cout<<endl;
cout<<"二叉树中序递归遍历
";
InOrderTraverse1(Tree);
cout<<endl;
cout<<"二叉树后序递归遍历
";
LastOrderTraverse1(Tree);
cout<<endl;
}
else if(choose==1)
{
cout<<"二叉树先序非递归遍历
";
PreOrderTraverse2(Tree);
cout<<endl;
cout<<"二叉树中序非递归遍历
";
InOrderTraverse2(Tree);
cout<<endl;
cout<<"二叉树后序非递归遍历
";
LastOrderTraverse2(Tree);
cout<<endl;
}
else
{
cout<<"输入错误
"<<endl;
}
return 0;
}