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)層序遍歷二叉樹利用的是隊列的先進先出原理。