1. 实验目的
(1)掌握二叉树的二叉链表存储方式及二叉树的特征;
(2)验证二叉树在二叉链表存储结构下遍历操作的实现。
2. 实验内容
(1)采用二叉链表结构建立二叉树;
(2)编程实现二叉树的先序、中序、后序和层序遍历;
(3)编程实现非递归中序遍历;
(4)编程实现:求二叉树的高度和叶子结点个数。
3. 实验步骤
(1)编写程序主框架;
(2)编写创建二叉树代码;
(3)编写实现二叉树先序遍历代码;
(4)编写实现二叉树非递归中序遍历代码;
(5)编写实现二叉树后序遍历代码;
(6)编写实现二叉树层序遍历代码;
(7)编写求二叉树高度代码;
(8)编写求二叉树叶子结点个数代码;
(9)编写代码实现哈夫曼算法。
4. 实验代码
#include <iostream>
using namespace std;
#define MAXSIZE 100
typedef char ElemType;
//二叉树
typedef struct BiTNode
{
ElemType data;
struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
//顺序栈
typedef struct
{
BiTree *base;
BiTree *top;
int stacksize;
}SqStack;
//循环队列
typedef struct
{
BiTree *base;
int frontq;
int rear;
}SqQueue;
void Tips();
//初始化顺序栈
void InitStack(SqStack &S);
//入栈
void Push(SqStack &S,BiTree e);
//出栈
void Pop(SqStack &S,BiTree &e);
//初始化顺序队列
void InitQueue(SqQueue &Q);
//入队
void enQueue(SqQueue &Q,BiTree e);
//出队
void deQueue(SqQueue &Q,BiTree &e);
//销毁队列
void DestroyQueue(SqQueue &Q);
//建立二叉树
void CreateBiTree(BiTree &T);
//先序遍历
void PreOrderTraverse(BiTree &T);
//后序遍历
void ProOrderTraverse(BiTree &T);
//中序遍历
void InOrderTraverse(BiTree &T);
//层序遍历
void SeOrderTraverse(BiTree &T);
//求二叉树深度
int Depth(BiTree T);
//求叶子结点个数
int NodeCount(BiTree T);
int main()
{
BiTree T;
int index;
Tips();
do
{
cout << "请输入操作代码:";
cin >> index;
switch(index)
{
case 1:
cout << "输入:";
CreateBiTree(T); //创建二叉树
break;
case 2:
PreOrderTraverse(T); //先序遍历
cout << endl;
break;
case 3:
ProOrderTraverse(T); //后序遍历
cout << endl;
break;
case 4:
InOrderTraverse(T); //非递归中序遍历
cout << endl;
break;
case 5:
SeOrderTraverse(T); //层序遍历
cout << endl;
break;
case 6:
cout << Depth(T) << endl; //求二叉树深度
break;
case 7:
cout << NodeCount(T) << endl; //求叶子结点个数
break;
default:
cout << "输入不合法!" << endl;
break;
}
}while(index>0);
return 0;
}
void Tips()
{
cout << "###### 1812050030-戴琦 ######" << endl;
cout << "1 ---------------- 创建二叉树" << endl;
cout << "2 ---------------- 先序遍历" << endl;
cout << "3 ---------------- 后序遍历" << endl;
cout << "4 ---------------- 非递归中序遍历" << endl;
cout << "5 ---------------- 层序遍历" << endl;
cout << "6 ---------------- 求二叉树深度" << endl;
cout << "7 ---------------- 求叶子结点个数" << endl;
cout << "输入0或负数退出程序!" << endl;
}
void InitStack(SqStack &S)
{
S.base = new BiTree[MAXSIZE];
if(S.base)
{
S.top = S.base;
S.stacksize = MAXSIZE;
}
}
void Push(SqStack &S,BiTree e)
{
if(S.top - S.base == MAXSIZE)
cout << "栈已满!" << endl;
else
*S.top++ = e;
}
void Pop(SqStack &S,BiTree &e)
{
if(S.base == S.top)
cout << "栈为空!" << endl;
else
e = *--S.top;
}
void InitQueue(SqQueue &Q)
{
Q.base = new BiTree[MAXSIZE];
if(Q.base)
{
Q.frontq = Q.rear = 0;
}
}
void enQueue(SqQueue &Q,BiTree e)
{
if(Q.frontq == (Q.rear+1)%MAXSIZE)
cout << "队列已满!" << endl;
else
{
Q.base[Q.rear] = e;
Q.rear = (Q.rear+1) % MAXSIZE;
}
}
void deQueue(SqQueue &Q,BiTree &e)
{
if(Q.frontq == Q.rear)
cout << "队列为空!" << endl;
else
{
e = Q.base[Q.frontq];
Q.frontq = (Q.frontq+1)%MAXSIZE;
}
}
void DestroyQueue(SqQueue &Q)
{
if(Q.base)
{
Q.frontq = Q.rear;
delete(Q.base);
}
}
void CreateBiTree(BiTree &T)
{
ElemType 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 ProOrderTraverse(BiTree &T)
{
if(T)
{
ProOrderTraverse(T->lchild);
ProOrderTraverse(T->rchild);
cout << T->data << " ";
}
}
void InOrderTraverse(BiTree &T)
{
SqStack S;
InitStack(S);
BiTree p = T;
BiTree q = new BiTNode;
while(p || S.base != S.top)
{
if(p)
{
Push(S,p);
p = p->lchild;
}
else
{
Pop(S,q);
cout << q->data << " ";
p = q->rchild;
}
}
}
void SeOrderTraverse(BiTree &T)
{
SqQueue SQ;
InitQueue(SQ);
BiTree p = T;
if(T)
{
enQueue(SQ,p);
while(SQ.frontq != SQ.rear)
{
deQueue(SQ,p);
cout << p->data << " ";
if(p->lchild)
enQueue(SQ,p->lchild);
if(p->rchild)
enQueue(SQ,p->rchild);
}
}
DestroyQueue(SQ);
}
int Depth(BiTree T)
{
int m,n;
if(T == NULL)
return 0;
else
{
n = Depth(T->lchild);
m = Depth(T->rchild);
if(n>m)
return n+1;
else
return m+1;
}
}
int NodeCount(BiTree T)
{
if(T == NULL)
return 0;
if(!T->lchild && !T->rchild)
return 1;
else
return NodeCount(T->lchild)+NodeCount(T->rchild);
}
5. 实验总结
(1)二叉树的遍历算法是其它运算的基础,通过遍历得到二叉树中结点访问的线性序列,实现了非线性结构的线性化。
(2)非递归中序遍历二叉树利用的是栈的后进先出原理;
(3)层序遍历二叉树利用的是队列的先进先出原理。