目录
【实验目的】
【实验预习】
【实验内容】
编写程序,实现二叉树的链式存储及基本操作
1. 掌握二叉树的基本存储表示。
2. 掌握二叉树的遍历操作实现方法(递归和非递归方法)。
3. 理解并实现二叉树的其他基本操作。
4. 掌握二叉树的重要应用——哈夫曼编码的实现。
1. 二叉树的二叉链表存储表示。
2. 二叉树的三种基本遍历方式。
3. 哈夫曼树和哈夫曼编码。
(1)填空:
① 按照先序序列建立二叉树。
读入的字符序列为:ABC##DE#G##F###
② 二叉树的三种遍历序列:
先序序列:ABCDEGF
中序序列:CBEGDFA
后续序列:CGEFDBA
③ 按层次遍历二叉树,得到的序列为:ABCDEFG
④ 二叉树的深度为:5
⑤ 二叉树的叶子结点数为:3
⑥ 交换二叉树所有结点的左右次序得到的新二叉树为:
⑦ 新二叉树的三种遍历序列分别为:
先序序列:ABDFEGC
中序序列:AFDGEBC
后序序列:FGEDCBA
(2)参考程序如下,请补充完整程序,并调试运行:
#include
#include
#define MAX 20
typedef struct BTNode{
char data;
struct BTNode *lchild;
struct BTNode *rchild;
}*BiTree;
typedef struct{
BiTree data[MAX];
int front,rear;
}SqQueue;
void createBiTree(BiTree *t); //先序遍历创建二叉树
void PreOrder(BiTree p); //先序遍历二叉树
void InOrder(BiTree p); //中序遍历二叉树
void PostOrder(BiTree p); //后序遍历二叉树
void RPreorder(BiTree p); //先序遍历的非递归算法
void RInorder(BiTree p); //中序遍历的非递归算法
void RPostorder(BiTree p); //后序遍历的非递归算法
int depth(BiTree t); //求二叉树的深度算法
BiTree gettreenode(char x,BiTree lptr,BiTree rptr); //后序复制二叉树——建立结点
BiTree copytree(BiTree t); //以后序遍历的方式复制二叉树
BiTree swap(BiTree b); //交换二叉树的结点的左右孩子
void ccOrder(BiTree t); //利用循环队列实现层次遍历
int Leaves(BiTree t); //统计二叉树叶子结点
void release(BiTree t); //释放二叉树
void createBiTree(BiTree *t){
char s;
BiTree q;
printf("\nplease input data:");
s=getchar();
getchar();
if(s=='#'){
*t=NULL;
return ;
}
q=(BiTree)malloc(sizeof(struct BTNode));
q->data=s;
*t=q;
createBiTree(&q->lchild);
createBiTree(&q->rchild);
}
void PreOrder(BiTree p){
if(p!=NULL){
printf("%c",p->data);
PreOrder(p->lchild);
PreOrder(p->rchild);
}
}
void InOrder(BiTree p){
if(p!=NULL){
InOrder(p->lchild);
printf("%c",p->data);
InOrder(p->rchild);
}
}
void PostOrder(BiTree p){
if(p!=NULL){
PostOrder(p->lchild);
PostOrder(p->rchild);
printf("%c",p->data);
}
}
void RPreorder(BiTree p){
BiTree stack[MAX],q;
int top=0,i;
for(i=0;iq=p;
while(q!=NULL){
printf("%c",q->data);
if(q->rchild!=NULL){
stack[top++]=q->rchild;
}
if(q->lchild!=NULL){
q=q->lchild;
}else if(top>0){
q=stack[--top];
}else{
q=NULL;
}
}
}
void RInorder(BiTree p){
BiTree stack[MAX],q;
int top=0,i;
for(i=0;iq=p;
while(q!=NULL||top>0){
while(q!=NULL){
stack[top++]=q;
q=q->lchild;
}
q=stack[--top];
printf("%c",q->data);
q=q->rchild;
}
}
void RPostorder(BiTree p){
BiTree stack[MAX],q;
int i,top=0,flag[MAX];
for(i=0;i
stack[i]=NULL;
flag[i]=0;
}
q=p;
while(q!=NULL||top!=0){
if(q!=NULL){
stack[top]=q;
flag[top]=0;
top++;
q=q->lchild;
}else{
while(top){
if(flag[top-1]==0){
q=stack[top-1];
q=q->rchild;
flag[top-1]=1;
break;
}else{
q=stack[--top];
printf("%c",q->data);
}
}
}
if(top==0) break;
}
}
int depth(BiTree t){
int hl,hr;
if(t==NULL){
return 0;
}else{
hl=depth(t->lchild);
hr=depth(t->rchild);
if(hl>hr){
return hl+1;
}else{
return hr+1;
}
}
}
void ccOrder(BiTree t){
BiTree p;
SqQueue qlist,*q;
q=&qlist;
q->rear=0;
q->front=0;
p=t;
if(p!=NULL){
printf("%c",p->data);
q->data[q->rear]=p;
q->rear=(q->rear+1)%MAX;
while(q->front!=q->rear){
p=q->data[q->front];
q->front=(q->front+1)%MAX;
if(p->lchild!=NULL){
printf("%c",p->lchild->data);
q->data[q->rear]=p->lchild;
q->rear=(q->rear+1)%MAX;
}
if(p->rchild!=NULL){
printf("%c",p->rchild->data);
q->data[q->rear]=p->rchild;
q->rear=(q->rear+1)%MAX;
}
}
}
}
BiTree gettreenode(char x,BiTree lptr,BiTree rptr){
BiTree t;
t=(BiTree)malloc(sizeof(struct BTNode));
t->data=x;
t->lchild=lptr;
t->rchild=rptr;
return t;
}
BiTree swap(BiTree b){
BiTree t,t1,t2;
if(b==NULL){
t=NULL;
}else{
t=(BiTree)malloc(sizeof(struct BTNode));
t->data=b->data;
t1=swap(b->lchild);
t2=swap(b->rchild);
t->lchild=t2;
t->rchild=t1;
}
return t;
}
void release(BiTree t){
if(t!=NULL){
release(t->lchild);
release(t->rchild);
free(t);
}
}
BiTree copytree(BiTree t){
BiTree newlptr,newrptr,newnode;
if(t==NULL){
return NULL;
}
if(t->lchild!=NULL){
newlptr=copytree(t->lchild);
}else{
newlptr=NULL;
}
if(t->rchild!=NULL){
newrptr=copytree(t->rchild);
}else{
newrptr=NULL;
}
newnode=gettreenode(t->data,newlptr,newrptr);
return newnode;
}
int Leaves(BiTree t){
int hl,hr;
if(t==NULL){
return 0;
}
if(t->lchild==NULL&&t->rchild==NULL){
return 1;
}else{
hl=Leaves(t->lchild);
hr=Leaves(t->rchild);
return hl+hr;
}
}
int main(){
BiTree t=NULL,copyt=NULL;
int select;
do{
printf("\n*****************MENU*****************\n");
printf("1. 按先序序列建立二叉树\n");
printf("2. 遍历二叉树(三种递归方法)\n");
printf("3. 遍历二叉树(三种非递归方法)\n");
printf("4. 层次遍历二叉树\n");
printf("5. 输出二叉树的深度\n");
printf("6. 统计二叉树的叶子结点数(递归)\n");
printf("7. 后序遍历方式复制一棵二叉树\n");
printf("8. 交换二叉树所有结点的左右孩子\n");
printf("0. EXIT");
printf("\n*****************MENU*****************\n");
printf("\ninput choice:");
scanf("%d",&select);
getchar();
switch(select){
case 1:
printf("\n1-按先序序列建立二叉树:\n");
printf("请依次输入结点序列:\n");
createBiTree(&t);
if(t!=NULL){
printf("二叉树创建成功!\n");
}else{
printf("二叉树创建失败!\n");
}
break;
case 2:
printf("\n2-遍历二叉树(三种递归方法):\n");
printf("\n先序遍历序列:");
PreOrder(t);
printf("\n中序遍历序列:");
InOrder(t);
printf("\n后序遍历序列:");
PostOrder(t);
printf("\n");
break;
case 3:
printf("\n3-遍历二叉树(三种非递归方法):\n");
printf("\n先序遍历序列:");
RPreorder(t);
printf("\n中序遍历序列:");
RInorder(t);
printf("\n后序遍历序列:");
RPostorder(t);
printf("\n");
break;
case 4:
printf("\n4-层次遍历二叉树:\n");
printf("\n按层次遍历:");
ccOrder(t);
printf("\n");
break;
case 5:
printf("\n5-输出二叉树的深度:\n");
printf("\n二叉树的深度:%d",depth(t));
printf("\n");
break;
case 6:
printf("\n6-统计二叉树的叶子结点个数(递归):\n");
printf("\n叶子结点数为:%d",Leaves(t));
printf("\n");
break;
case 7:
printf("\n7-后序遍历方式复制一棵二叉树:\n");
copyt=copytree(t);
if(copyt!=NULL){
printf("\n先序递归遍历复制的二叉树:");
PreOrder(copyt);
}else{
printf("\n复制失败!");
}
printf("\n");
break;
case 8:
printf("\n8-交换二叉树所有结点的左右孩子:\n");
printf("\n先序递归遍历交换后的二叉树:");
PreOrder(swap(t));
printf("\n");
break;
case 0:
release(t);
break;
}
}while(select);
return 0;
}