实验性质:综合性实验
要求:
(1) 采用二叉链表结构建立二叉树;
(2) 编程实现二叉树的先序、中序、后序和层序遍历;
(3) 编程实现非递归中序遍历
(3) 编程实现:求二叉树的高度和叶子结点个数;
目的:
(1)掌握二叉树的二叉链表存储方式及二叉树的特征;
(2)验证二叉树在二叉链表存储结构下遍历操作的实现;
示例
-
创建
输入 :ABC##DE#G##F###
该输入对应的树如图所示
-
先序 屏幕输出 A B C D E G F
-
后序 屏幕输出 C G E F D B A
-
中序 屏幕输出 C B E G D F A
-
(中序非递归还需看源代码)
-
层序 屏幕输出 A B C D E F G
-
深度 屏幕显示 深度为5
代码
#include <iostream>
#define QElemType BiTree
#define SElemType BiTree
#define MAXSIZE 30
using namespace std;
typedef char TElemType;
//定义二叉链表存储结构
typedef struct BiTNode
{
TElemType data; //数据域
struct BiTNode *lchild,*rchild; //指针域
}BiTNode,*BiTree;
//循环队列类型定义
typedef struct
{
QElemType *base;
int front;
int rear;
}SqQueue;
//顺序栈定义
typedef struct
{
SElemType *base;
SElemType *top;
int stacksize;
}SqStack;
//二叉树
void InitBiTree(BiTree &T); //构造空二叉树
void CreateBiTree(BiTree &T);//先序遍历建立二叉链表
void PreOrderTraverse(BiTree T); //先序遍历
void InOrderTraverse(BiTree T); //中序遍历
void PostOrderTraverse(BiTree T); //后序遍历
void LevelOrderTraverse(BiTree T); //层序遍历
void InOrderTraverse2(BiTree T); //非递归中序遍历
int Depth(BiTree T); //计算二叉树深度
int LeafCount(BiTree bt); //计算叶子节点个数
//顺序栈
bool InitStack(SqStack &S); //顺序栈的初始化
bool Push(SqStack &S,SElemType e);//顺序栈的入栈
bool Pop(SqStack &S,SElemType e); //删除栈顶元素
bool StackEmpty(SqStack S);
SElemType GetTop(SqStack S); //取栈顶元素
//队列
bool InitQueue(SqQueue &Q);//初始化队列
bool EnQueue(SqQueue &Q,QElemType e);//元素入队
bool DeQueue(SqQueue &Q,QElemType &e);//元素出队
bool DestroyQueue(SqQueue &Q);//销毁队列
bool QueueEmpty(SqQueue Q);//队列判空
void Menu(); //文字菜单提示信息
int main()
{
BiTree T;
InitBiTree(T);
Menu();
int i; //输入的数字
cout<<"请输入操作代码:";
cin>>i;
while(true)
{
switch(i)
{
case 1:
cout<<"输入字符序列,#代表空:";
CreateBiTree(T);
cout<<"创建成功"<<endl;
break;
case 2:
cout<<"先序遍历结果为:";
PreOrderTraverse(T);
cout<<endl;
break;
case 3:
cout<<"中序遍历结果为:";
InOrderTraverse(T);
cout<<endl;
break;
case 4:
cout<<"后序遍历结果为:";
PostOrderTraverse(T);
cout<<endl;
break;
case 5:
cout<<"层序遍历结果为:";
LevelOrderTraverse(T);
cout<<endl;
break;
case 6:
cout<<"非递归中序遍历结果为:";
InOrderTraverse2(T);
cout<<endl;
break;
case 7:
cout<<"二叉树深度为:"<<Depth(T)<<endl;
break;
case 8:
cout<<"二叉树叶子结点个数为:"<<LeafCount(T)<<endl;
break;
default:
if(i<0)
return 0;
else
{
cout<<"输入的位置非法,请重新输入";
break;
}
}
cout<<"请输入操作代码:";
cin>>i;
}
return 0;
}
//二叉树
void InitBiTree(BiTree &T)
{
T = new BiTNode;
T->lchild = T->rchild = NULL;
T->data = '#';
}
void CreateBiTree(BiTree &T) //先序遍历建立二叉链表
{
char ch;
cin>>ch;
if(ch=='#')
T=NULL;
else
{
T=new BiTNode;
T->data=ch;
CreateBiTree(T->lchild); //递归创建左子树
CreateBiTree(T->rchild); //递归创建右子树
}
}
void PreOrderTraverse(BiTree T) //先序遍历
{
if(T)
{
cout<<T->data; //访问根节点
PreOrderTraverse(T->lchild); //先序遍历左子树
PreOrderTraverse(T->rchild);
}
}
void InOrderTraverse(BiTree T) //中序遍历
{
if(T)
{
InOrderTraverse(T->lchild); //中序遍历左子树
cout<<T->data; //访问根节点
InOrderTraverse(T->rchild);
}
}
void PostOrderTraverse(BiTree T) //后序遍历
{
if(T)
{
PostOrderTraverse(T->lchild); //后序遍历左子树
PostOrderTraverse(T->rchild);
cout<<T->data; //访问根节点
}
}
void LevelOrderTraverse(BiTree T) //层序遍历
{
//将每一层的节点分别入队列,然后分别读取,读取后继续将它们的子节点入队,所以保证是按照一层一层来遍历的
BiTree P=T;
SqQueue Q;
InitQueue(Q); //初始化队列
if(P)
{
EnQueue(Q,P);
while(!QueueEmpty(Q))
{
DeQueue(Q,P); //出队列
cout<<P->data;
if(P->lchild)
EnQueue(Q,P->lchild);
if(P->rchild)
EnQueue(Q,P->rchild);
}
}
DestroyQueue(Q);
}
void InOrderTraverse2(BiTree T) //非递归中序遍历
{
SqStack S;InitStack(S);
BiTree p=T;BiTree q=new BiTNode;
while(p||!StackEmpty(S))
{
if(p)
{
Push(S,p);
p=p->lchild;
}
else
{
q=GetTop(S);
Pop(S,q);
cout<<q->data;
p=q->rchild;
}
}
}
int Depth(BiTree T)
{
if(T==NULL) return 0;
else
{
int m=Depth(T->lchild);
int n=Depth(T->rchild);
if(m>n)
return(m+1);
else
return(n+1);
}
}
int LeafCount(BiTree T)
{
if(!T) //结点为空
return 0;
if(!T->lchild&&!T->rchild) //没有子节点了
return 1;
else
return LeafCount(T->lchild)+LeafCount(T->rchild);
}
//顺序栈
bool InitStack(SqStack &S) //顺序栈的初始化
{
S.base=new SElemType[MAXSIZE];
if(!S.base)
return 0;
else
{
S.top=S.base; //top初始化为base,空栈
S.stacksize=MAXSIZE;
return 1;
}
}
bool Push(SqStack &S,SElemType e)//顺序栈的入栈
{
if(S.top-S.base==S.stacksize)
return 0;
else
{
*S.top++=e;
return 1;
}
}
bool Pop(SqStack &S,SElemType e) //删除栈顶元素
{
if(S.top==S.base)
return 0;
e=*--S.top;
return 1;
}
bool StackEmpty(SqStack S)
{
if(S.top==S.base)
return true;
else
return false;
}
SElemType GetTop(SqStack S)
{
if(S.top!=S.base)
return *(S.top-1);
}
//队列
bool InitQueue(SqQueue &Q)//构造一个空队列
{
Q.base=new QElemType[MAXSIZE];
if(!Q.base)
return 0;
Q.front=Q.rear=0;
return 1;
}
bool EnQueue(SqQueue &Q,QElemType e)//元素入队
{
if((Q.rear+1)%MAXSIZE==Q.front)
return 0;
Q.base[Q.rear]=e;
Q.rear=(Q.rear+1)%MAXSIZE;
return 1;
}
bool DeQueue(SqQueue &Q,QElemType &e)//元素出队
{
if(Q.front==Q.rear)
return 0;
e=Q.base[Q.front];
Q.front=(Q.front+1)%MAXSIZE;
return 1;
}
bool QueueEmpty(SqQueue Q)//判断队列是否为空
{
if(Q.rear==Q.front)
return 1;
else
return 0;
}
bool DestroyQueue(SqQueue &Q)//销毁队列
{
if(!Q.base)
return 0;
Q.rear=Q.front;
delete Q.base;
return 1;
}
void Menu()
{
cout << "---------------------------" << endl;
cout << "****by 夏日****" << endl;
cout << "---------------------------" << endl;
cout << "1-----创建二叉链表 "<< endl;
cout << "2-----先序遍历" << endl;
cout << "3-----中序遍历" << endl;
cout << "4-----后序遍历" << endl;
cout << "5-----层序遍历" << endl;
cout << "6-----非递归中序遍历" << endl;
cout << "7-----二叉树深度" << endl;
cout << "8-----二叉树叶子结点个数" << endl;
cout << " 退出,输入一个负数!" << endl;
}
输出示例
写在最后
本文章仅供个人复习使用,如有错误,请联系我更正。