数据结构–树及其应用-- 二叉树的遍历
【实验目的】
使学生深入了解并掌握非线性数据结构的特点,掌握创建二叉树二叉链表存储结构的方法;同时深刻理解二叉树的各遍历过程。
【实验内容及要求】
1、问题描述:很多涉及二叉树的操作的算法都是以二叉树的遍历操作为基础的。编写程序,对一棵给定的二叉树进行先、中、后三种次序的遍历。
2、基本要求:以二叉链表为存储结构,实现二叉树的先、中、后三种次序的递归和非递归遍历。
3、测试数据:以教科书图6.9的二叉树为例。
4、实现提示:
(1)设二叉树的结点不超过30个,且每个结点的数据均为字符,这样可利用先序遍历序列作为输入顺序创建二叉树链表存储结构。
(2)也可利用完全二叉树在顺序存储中的特性,创建二叉树的存储结构,此时,二叉树中结点数据的类型不受限制。
5、选作内容:
(1)借助队列,实现二叉树的层序遍历。
(2)按凹入表或树形打印所遍历的二叉树。
【实验数据】
#include <iostream>
#include <stack>
#include <cstdlib>
using namespace std;
typedef struct BiTNode
{
char data;
struct BiTNode *lchild,*rchild;
} BiTNode, *BiTree;
void InitBiTree(BiTree &T)//构造空二叉树
{
T=NULL;
}
void CreateBiTree(BiTree &T)//生成二叉树
{
char ch;
cin>>ch;
if(ch=='0')//0代表空
T=NULL;
else
{
T=new BiTNode;//生成根结点
if(!T)
{
cout<<"生成结点错误!"<<endl;
return;
}
T->data=ch;
CreateBiTree(T->lchild);
CreateBiTree(T->rchild);
}
}
void PreOrderTraverse(BiTree T)//先序递归遍历
{
if(T!=NULL)
{
cout<<T->data<<" ";
PreOrderTraverse(T->lchild);
PreOrderTraverse(T->rchild);
}
}
void RePreOrderTraverse(BiTree T)//先序非递归遍历
{
stack<BiTree> s;
BiTree p=T;
while(p || !s.empty())
{
if(p)
{
cout<<p->data<<" ";
s.push(p);
p=p->lchild;
}
else
{
p=s.top();
p=p->rchild;
s.pop();
}
}
}
void InOrderTraverse(BiTree T)//中序递归遍历
{
if(T!=NULL)
{
InOrderTraverse(T->lchild);
cout<<T->data<<" ";
InOrderTraverse(T->rchild);
}
}
void ReInOrderTraverse(BiTree T)//中序非递归遍历
{
stack<BiTree> s;
BiTree p=T;
while(p || !s.empty())
if(p)
{
s.push(p);
p=p->lchild;
}
else
{
p=s.top();
cout<<p->data<<" ";
s.pop();
p=p->rchild;
}
}
void PostOrderTraverse(BiTree T)//后序递归遍历
{
if(T!=NULL)
{
PostOrderTraverse(T->lchild);
PostOrderTraverse(T->rchild);
cout<<T->data<<" ";
}
}
void RePostOrderTraverse(BiTree T)//后序非递归遍历
{
stack<BiTree> s;
BiTree p=T,r;
while(p || !s.empty())
{
if(p) //走到最左边
{
s.push(p);
p=p->lchild;
}
else //向右
{
p=s.top();//取栈顶结点
if(p->rchild && p->rchild!=r)//如果右子树存在,且未被访问过
{
p=p->rchild;
s.push(p);
p=p->lchild; //再走到最左
}
else //否则,访问栈顶结点并弹出
{
cout<<p->data<<" ";
r=p; //记录该结点
s.pop();
p=NULL; //结点访问完后,重置p指针
}
}
}
}
int main()
{
BiTree T;
CreateBiTree(T);
cout<<"PreOrderTraverse:" ;
PreOrderTraverse(T);
cout<<endl;
cout<<"InOrderTraverse:" ;
InOrderTraverse(T);
cout<<endl;
cout<<"PostOrderTraverse:" ;
PostOrderTraverse(T);
cout<<endl;
cout<<"PreOrderTraverse(Non-recursive):" ;
RePreOrderTraverse(T);
cout<<endl;
cout<<"InOrderTraverse(Non-recursive):" ;
ReInOrderTraverse(T);
cout<<endl;
cout<<"PostOrderTraverse(Non-recursive):" ;
RePostOrderTraverse(T);
cout<<endl;
system("pause");
return 0;
}