《数据结构与算法》实验指导与报告书exp6Bitree.docx

上传人:b****6 文档编号:3970954 上传时间:2022-11-26 格式:DOCX 页数:17 大小:26.27KB
下载 相关 举报
《数据结构与算法》实验指导与报告书exp6Bitree.docx_第1页
第1页 / 共17页
《数据结构与算法》实验指导与报告书exp6Bitree.docx_第2页
第2页 / 共17页
《数据结构与算法》实验指导与报告书exp6Bitree.docx_第3页
第3页 / 共17页
《数据结构与算法》实验指导与报告书exp6Bitree.docx_第4页
第4页 / 共17页
《数据结构与算法》实验指导与报告书exp6Bitree.docx_第5页
第5页 / 共17页
点击查看更多>>
下载资源
资源描述

《数据结构与算法》实验指导与报告书exp6Bitree.docx

《《数据结构与算法》实验指导与报告书exp6Bitree.docx》由会员分享,可在线阅读,更多相关《《数据结构与算法》实验指导与报告书exp6Bitree.docx(17页珍藏版)》请在冰豆网上搜索。

《数据结构与算法》实验指导与报告书exp6Bitree.docx

《数据结构与算法》实验指导与报告书exp6Bitree

 

《数据结构与算法》实验指导与报告书

 

______学年第____学期

 

专业:

___________________________________________

学号:

___________________________________________

姓名:

___________________________________________

实验名称:

___________________________________________

实验地点:

___________________________________________

指导教师:

___________________________________________

 

计算机科学与工程学院

2014

实验六二叉树

【实验目的】

1、掌握二叉树的基本存储表示。

2、掌握二叉树的遍历操作实现方法(递归和非递归方法)。

3、理解并实现二叉树的其他基本操作。

4、掌握二叉树的重要应用---哈夫曼编码的实现。

【实验学时】

4-6学时

【实验预习】

回答以下问题:

1、二叉树的二叉链表存储表示。

 

2、二叉树的三种基本遍历方式。

 

3、解释哈夫曼树和带权路径长度WPL。

 

【实验内容和要求】

1、编写程序exp6_1.c,实现二叉树的链式存储及基本操作。

以下图所示的二叉树实现二叉树的二叉链表存储及基本操作,回答下列问题,补充完整程序,并调试运行验证结果。

(1)按照先序序列建立该二叉树。

读入的字符序列为应为:

__________________________________(*表示空指针)。

(2)该二叉树的三种遍历序列:

先序序列:

__________________________;

中序序列:

__________________________;

后序序列:

__________________________;

(3)按层次遍历该二叉树,得到的序列为:

_______________________。

(4)该二叉树的深度为:

________。

(5)该二叉树的叶子结点数为:

___________。

(6)交换该二叉树所有结点的左右次序得到的新二叉树为:

(画出新二叉树的图)

 

(7)新二叉树的三种遍历序列分别为:

先序序列:

__________________________;

中序序列:

__________________________;

后序序列:

__________________________;

exp6_1.c参考程序如下:

#include

#include

#defineMAX20

/*---二叉树的二叉链表存储表示---*/

typedefstructBTNode

{

chardata;/*结点数据*/

structBTNode*lchild;/*左孩子指针*/

structBTNode*rchild;/*右孩子指针*/

}*BiTree;

/*---非递归遍历辅助队列---*/

typedefstruct

{

BiTreedata[MAX];

intfront,rear;

}queue;

voidcreateBiTree(BiTree*t);/*先序遍历创建二叉树*/

voidPreOrder(BiTreep);/*先序遍历二叉树*/

voidInOrder(BiTreep);/*中序遍历二叉树*/

voidPostOrder(BiTreep);/*后序遍历二叉树*/

voidRPreorder(BiTreep);/*先序遍历的非递归算法*/

voidRInorder(BiTreep);/*中序遍历的非递归算法*/

voidRPostorder(BiTreep);/*后序遍历的非递归算法*/

intdepth(BiTreet);/*求二叉树的深度算法*/

BiTreegettreenode(charx,BiTreelptr,BiTreerptr);/*后序复制二叉树-建立结点*/

BiTreecopytree(BiTreet);/*以后序遍历的方式复制二叉树*/

BiTreeswap(BiTreeb);/*交换二叉树的结点的左右孩子*/

voidccOrder(BiTreet);/*利用循环队列实现层次遍历*/

intLeaves(BiTreet);/*统计二叉树叶子结点(递归)*/

voidrelease(BiTreet);/*释放二叉树*/

/*先序遍历创建二叉树*/

voidcreateBiTree(BiTree*t)

{

chars;

BiTreeq;

printf("\npleaseinputdata:

");

s=getchar();

getchar();/*扔掉存在键盘缓冲区的输入结束回车符*/

if(s=='*')/*子树为空则返回*/

{

*t=NULL;

return;

}

q=(BiTree)malloc(sizeof(structBTNode));

if(q==NULL)

{

printf("Memoryallocfailure!

");

exit(0);

}

q->data=s;

*t=q;

createBiTree(&q->lchild);/*递归建立左子树*/

createBiTree(&q->rchild);/*递归建立右子树*/

}/*createBiTree*/

/*先序遍历二叉树,补充递归算法*/

voidPreOrder(BiTreep)

{

 

}/*PreOrder*/

/*中序遍历二叉树,补充递归算法*/

voidInOrder(BiTreep)

{

 

}/*InOrder*/

/*后序遍历二叉树,补充递归算法*/

voidPostOrder(BiTreep)

{

 

}/*PostOrder*/

/*先序遍历的非递归算法*/

voidRPreorder(BiTreep)

{

BiTreestack[MAX],q;

inttop=0,i;

for(i=0;i

q=p;

while(q!

=NULL)

{

printf("%c",q->data);

if(q->rchild!

=NULL)_______________________;/*右指针进栈*/

if(q->lchild!

=NULL)q=q->lchild;/*顺着左指针继续向下*/

elseif(top>0)q=stack[--top];/*左子树访问完,出栈继续访问右子树结点*/

elseq=NULL;

}

}/*RPreorder*/

/*中序遍历的非递归算法*/

voidRInorder(BiTreep)

{

 

}/*RInorder*/

/*后序遍历的非递归算法*/

voidRPostorder(BiTreep)

{

BiTreestack[MAX],q;

inti,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;

}

}/*RPostorder*/

/*求二叉树的深度算法,补充递归算法*/

intdepth(BiTreet)

{

 

}/*depth*/

/*建立结点*/

BiTreegettreenode(charx,BiTreelptr,BiTreerptr)

{

BiTreet;

t=(BiTree)malloc(sizeof(structBTNode));

t->data=x;

t->lchild=lptr;

t->rchild=rptr;

return(t);

}/*gettreenode*/

/*以后序遍历的方式递归复制二叉树*/

BiTreecopytree(BiTreet)

{

BiTreenewlptr,newrptr,newnode;

if(t==NULL)

returnNULL;

if(t->lchild!

=NULL)

newlptr=copytree(t->lchild);

elsenewlptr=NULL;

if(t->rchild!

=NULL)

newrptr=copytree(t->rchild);

elsenewrptr=NULL;

newnode=gettreenode(t->data,newlptr,newrptr);

return(newnode);

}/*copytree*/

/*交换二叉树的结点的左右孩子*/

BiTreeswap(BiTreeb)

{

BiTreet,t1,t2;

if(b==NULL)

t=NULL;

else

{

t=(BiTree)malloc(sizeof(structBTNode));

t->data=b->data;

t1=swap(b->lchild);/*递归交换左子树上的结点*/

t2=swap(b->rchild);/*递归交换右子树上的结点*/

t->lchild=t2;/*交换根t的左右子树*/

t->rchild=t1;

}

return(t);

}/*swap*/

/*利用循环队列实现层次遍历*/

voidccOrder(BiTreet)

{

 

}/*ccOrder*/

/*统计二叉树叶子结点,补充递归算法*/

intLeaves(BiTreet)

{

 

}/*Leaves*/

/*释放二叉树*/

voidrelease(BiTreet)

{

if(t!

=NULL)

{

release(t->lchild);

release(t->rchild);

free(t);

}

}/*release*/

intmain()

{

BiTreet=NULL,copyt=NULL;

intselect;

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("\ninputchoice:

");

scanf("%d",&select);

getchar();

switch(select)

{

case1:

printf("\n1-按先序序列建立二叉树:

\n");

printf("请依次输入结点序列:

\n");

createBiTree(&t);

if(t!

=NULL)

printf("二叉树创建成功!

\n");

else

printf("二叉树未创建成功!

\n");

break;

case2:

printf("\n2-遍历二叉树(三种递归方法):

\n");

printf("\n先序遍历序列:

");

PreOrder(t);

printf("\n中序遍历序列:

");

InOrder(t);

printf("\n后序遍历序列:

");

PostOrder(t);

printf("\n");

break;

case3:

printf("\n3-遍历二叉树(三种非递归方法):

\n");

printf("\n先序遍历的非递归:

");

RPreorder(t);

printf("\n中序遍历的非递归:

");

RInorder(t);

printf("\n后序遍历的非递归:

");

RPostorder(t);

printf("\n");

break;

case4:

printf("\n4-层次遍历二叉树:

\n");

printf("\n按层次遍历:

");

ccOrder(t);

printf("\n");

break;

case5:

printf("\n5-输出二叉树的深度:

\n");

printf("\n二叉树的深度:

%d",depth(t));

printf("\n");

break;

case6:

printf("\n6-统计二叉树的叶子结点数(递归):

\n");

printf("\n叶子结点数为:

%d",Leaves(t));

printf("\n");

break;

case7:

printf("\n7-后序遍历方式复制一棵二叉树:

\n");

copyt=copytree(t);

if(copyt!

=NULL)

{

printf("\n先序递归遍历复制的二叉树:

");

PreOrder(copyt);

}

else

printf("\n复制失败!

");

printf("\n");

break;

case8:

printf("\n8-交换二叉树所有结点的左右孩子:

\n");

printf("\n先序递归遍历交换后的二叉树:

");

PreOrder(swap(t));/*如需输出中序和后序遍历的结果,增加调用*/

printf("\n");

break;

case0:

release(t);/*释放二叉树*/

break;

default:

break;

}

}

while(select);

return0;

}

2、编写程序exp6_2.c,实现哈夫曼树的建立和哈夫曼编码。

若有一组字符序列{a,c,e,i,s,t,w},对应的出现频率为{10,1,15,12,3,4,13}。

以此序列创建哈夫曼树和哈夫曼编码。

回答下列问题,补充完整程序,并调试运行验证结果。

(1)构造该序列的哈夫曼树,画出哈夫曼树的形态。

(以结点值左小右大的原则)

 

(2)写出对应的哈夫曼编码。

 

(3)计算编码的WPL。

 

exp6_2.c程序代码参考如下:

#include

#defineMAXVALUE10000/*定义最大权值*/

#defineMAXLEAF30/*定义哈夫曼树中叶子结点个数*/

#defineMAXNODEMAXLEAF*2-1

#defineMAXBIT10/*定义哈夫曼编码的最大长度*/

typedefstruct/*哈夫曼编码结构*/

{

intbit[MAXBIT];

intstart;

}

HCodeType;

typedefstruct/*哈夫曼树结点结构*/

{

chardata;

intweight;

intparent;

intlchild;

intrchild;

}

HNodeType;

voidHuffmanTree(HNodeTypeHuffNode[],int*hn);

voidHuffmanCode(HNodeTypeHuffNode[],HCodeTypeHuffCode[],intn);

voidHuffmanTree(HNodeTypeHuffNode[],int*hn)/*哈夫曼树的构造算法*/

{

inti,j,m1,m2,x1,x2,n;

printf("n:

");

scanf("%d",&n);

getchar();/*输入叶子结点个数*/

for(i=0;i<2*n-1;i++)/*数组HuffNode[]初始化*/

{

;

;

;

;

;

}

printf("HuffNode:

\n");

for(i=0;i

{

scanf("%c,%d",&HuffNode[i].data,&HuffNode[i].weight);/*输入n个叶子结点的权值*/

getchar();

}

for(i=0;i

{

m1=m2=MAXVALUE;

x1=x2=0;

for(j=0;j

{

if(HuffNode[j].weight

{

m2=m1;

x2=x1;

m1=HuffNode[j].weight;

x1=j;

}

elseif(HuffNode[j].weight

{

m2=HuffNode[j].weight;

x2=j;

}

}

/*将找出的两棵子树合并为一棵子树*/

HuffNode[x1].parent=n+i;

HuffNode[x2].parent=n+i;

HuffNode[n+i].weight=;

HuffNode[n+i].lchild=x1;

HuffNode[n+i].rchild=x2;

}

*hn=n;

}

voidHuffmanCode(HNodeTypeHuffNode[],HCodeTypeHuffCode[],intn)/*生成哈夫曼编码*/

{

HCodeTypecd;

inti,j,c,p;

for(i=0;i

{

cd.start=n-1;

c=i;

p=HuffNode[c].parent;

while(p!

=-1)/*由叶结点向上直到树根*/

{

if(HuffNode[p].lchild==c)

;/*左分支编码为0*/

else

;/*右分支编码为1*/

cd.start--;

c=p;

p=HuffNode[c].parent;

}

for(j=cd.start+1;j

HuffCode[i].bit[j]=cd.bit[j];

HuffCode[i].start=cd.start;

}

for(i=0;i

{

printf("%c:

",HuffNode[i].data);

for(j=HuffCode[i].start+1;j

printf("%d",HuffCode[i].bit[j]);

printf("\n");

}

}

intmain()

{

HNodeTypeHuffNode[MAXNODE];

HCodeTypeHuffCode[MAXLEAF];

intn,i;

printf("createHuffmanTree:

\n");

HuffmanTree(HuffNode,&n);

printf("\n");

for(i=0;i<2*n-1;i++)

{

putchar(HuffNode[i].data);

printf("%3d",HuffNode[i].weight);

printf("%3d",HuffNode[i].parent);

printf("%3d",HuffNode[i].lchild);

printf("%3d",HuffNode[i].rchild);

printf("\n");

}

printf("\n");

HuffmanCode(HuffNode,HuffCode,n);

return0;

}

【拓展实验】

3、实现哈夫曼的解码功能。

在上题的基础上,根据给定的哈夫曼编码译文,进行解码,输出原字符编码。

 

【实验小结】

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高中教育 > 小学教育

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1