用递归和循环的方式,实现对二叉树的三种遍历(先序、中序和后序遍历)。此外,包括了宽度搜索遍历(使用队列)和深度搜索遍历(使用栈)。(运行环境:VS2012)
//二叉树的遍历(可用循环或递归实现)
#include <iostream>
#include <stack>
#include <queue>
using namespace std;
int num;
struct BiNode
{
char name;
BiNode *lchild, *rchild; //左右子树
};
//先根遍历创建二叉树(递归)(先序输入结点,注意输入顺序)
BiNode *createBiNode(char *c, int n) //结点名存储在c中,共n个结点(形参可为数组名或指针)
{
BiNode *T=new BiNode;
num++;
if((num>n) || (c[num]=='0') ) //超限或已到末尾
return NULL;
if (c[num]=='#') T=NULL; //此时会跳出递归,左或右结点为空的情况用空格表示
else
{
T->name=c[num];
T->lchild=createBiNode(c,n); //c已经更新
T->rchild=createBiNode(c,n);
}
return T; //返回根结点的值
}
//递归先序输出
void preorderTraverse(BiNode *T) //先序
{
if (T)
{
cout<<T->name<<" ";
preorderTraverse(T->lchild);
preorderTraverse(T->rchild);
}
}
//循环非递归先序遍历(使用栈)
void preorderTraverse2(BiNode *T)
{
BiNode *node=T; //T为head
stack<BiNode*>nodes;
while(!nodes.empty()||node)
{
while(node) //从根结点开始遍历左子树到底
{
cout<<node->name<<" "; //从中间结点开始输出
nodes.push(node);
node=node->lchild;
}
if(!nodes.empty()) //左子树为空,该进入右子树
{
node=nodes.top(); //缺少左子树的最后一个结点(中序遍历时在此输出,无其他异同)
nodes.pop();
node=node->rchild; //从次级根结点开始重复上述的while过程
}
}
}
void inorderTraverse(BiNode *T) //中序
{
if (T)
{
inorderTraverse(T->lchild);
cout<<T->name<<" ";
inorderTraverse(T->rchild);
}
}
void postorderTraverse(BiNode *T) //后序
{
if (T)
{
postorderTraverse(T->lchild);
postorderTraverse(T->rchild);
cout<<T->name<<" ";
}
}
//循环后序遍历(需判断上次访问的结点是右子树还是左子树,若是右子树则访问根结点,若是左子树,则先进入右子树访问)
void postorderTraverse2(BiNode *T)
{
BiNode *node=T; //T为head (当前访问结点)
BiNode *node2=NULL; //(记录上次访问的结点)
stack<BiNode*>nodes;
while(node) //移到一个最后左子树
{
nodes.push(node);
node=node->lchild;
}
while(!nodes.empty())
{
node=nodes.top();
nodes.pop();
if (node->rchild==NULL || node->rchild==node2) //右子树为空或右子树已经被访问过时访问根结点
{
cout<<node->name<<" ";
node2=node;
}
else
{
nodes.push(node);
node=node->rchild; //进入次级根结点的右子树
while(node)
{
nodes.push(node);
node=node->lchild;
}
}
}
cout<<" ";
}
//循环宽度搜索遍历(按层遍历)
void width(BiNode *T)
{
queue<BiNode*> nodes;
BiNode *node;
nodes.push(T);
while (!nodes.empty()) //队列不为空
{
node=nodes.front(); //.rear指向末尾
nodes.pop();
cout<<node->name;
if (node->lchild)
nodes.push(node->lchild);
if (node->rchild)
nodes.push(node->rchild);
}
}
//深度搜索遍历,先遍历完左子树,再遍历右子树,利用栈,先将右子树压栈,再将左子树压栈
void depth(BiNode *T)
{
stack<BiNode*> nodes;
nodes.push(T);
BiNode *node; //临时结点变量
while (!nodes.empty())
{
node=nodes.top();
cout<<node->name;
nodes.pop();
if (node->rchild) //先将右子树压栈,再将左子树压栈
nodes.push(node->rchild);
if (node->lchild)
nodes.push(node->lchild);
}
}
int main()
{
int i=1,n,a;
num=0;
cout<<"请输入结点数:";
cin>>n;
char c[100]; //声明数组,指明数组个数
cout<<"请输入每个结点名:";
for (i=1;i<=n;i++)
cin>>c[i];
BiNode *BiTree=createBiNode(c,n); //实参为数组名,数组首地址
cout<<"先序输出: \n";
preorderTraverse(BiTree);
cout<<"\n";
cout<<"循环先序输出: \n";
preorderTraverse2(BiTree);
cout<<"\n";
cout<<"中序输出: \n";
inorderTraverse(BiTree);
cout<<"\n";
cout<<"后序输出:\n";
postorderTraverse(BiTree);
cout<<"\n";
cout<<"循环后序输出:\n";
postorderTraverse2(BiTree);
cout<<"\n";
cout<<"宽度遍历输出:\n";
width(BiTree);
cout<<"\n";
cout<<"深度遍历输出:\n";
depth(BiTree);
cout<<"\n";
system("pause"); //防闪退
return 0;
}