ImageVerifierCode 换一换
格式:DOCX , 页数:17 ,大小:439.27KB ,
资源ID:23758228      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/23758228.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(赫夫曼树数据结构课程设计.docx)为本站会员(b****8)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

赫夫曼树数据结构课程设计.docx

1、赫夫曼树数据结构课程设计赫夫曼树的建立1.设计目的本课程设计是为了配合数据结构课程的开设,通过设计一完整的程序,使学生掌握数据结构的应用、算法的编写、类C语言的算法转换成C程序并用TC上机调试的基本方法。 建立函数输入一个二叉树的结点个数及其所对应的权值,建立其对应的赫夫曼树,并输出其对应的赫夫曼编码。通过设计程序,了解并掌握赫夫曼树的各种性质及其存储结构,学会赫夫曼编码的求解过程,并了解赫夫曼编码的广泛用途,掌握链表的灵活运用;学习链表初始化和建立一个新的单循环链表,并学会分析链表功能选择合适链表进行编程。2.设计方案论证2.1 问题描述赫夫曼树又称最优二叉树,是一种带权路径长度最短的二叉树

2、。所谓树的带权路径长度,就是树中所有的叶结点的权值乘上其到根结点的路径长度(若根结点为0层,叶结点到根结点的路径长度为叶结点的层数)。树的带权路径长度记为WPL=(W1*L1+W2*L2+W3*L3+.+ Wn*Ln),N个权值Wi(i=1,2,.n)构成一棵有N个叶结点的二叉树,相应的叶结点的路径长度为Li(i=1,2,.n)。可以证明哈夫曼树的WPL是最小的。2.2建立赫夫曼树的算法思想(1) 从n个权值W1,W2,Wn构造n棵只有一个结点的二叉树,其中每棵 二叉树的左右子树均为空,从而得到n棵树的森林=T1,T2,Tn(2)在森林中,选出权值最小和次最小的二叉树分别作为左子树和右子树,构

3、造一棵新的二叉树,且新二叉树根的权值为其左右子树上根结点的权值之和。 (3)在森林中删除这两棵二叉树,同时把新的二叉树加入到森林中。(4)重复2和3两步骤,直到森林中只有一棵树为止,这棵树便是哈夫曼树。2.3赫夫曼树的构造过程下图展示了赫夫曼树的构造过程,其中根节点上标注的数字是所赋的权值。图1赫夫曼树的构造过程可以计算得到该赫夫曼树的路径长度:WPL(12+8)*3+2*15+1*17=107。2.4赫夫曼编码求解过程编写求赫夫曼编码操作就是按照建立赫夫曼树的算法思想建立一棵赫夫曼树,然后自底向上求得叶子结点(既每个字符)的赫夫曼编码。步骤1:以4个带权7,2,5,4字符为例,手动实现求解这

4、4个字符的赫夫曼编码。假设字符个数为n,则这棵赫夫曼树HT中结点个数为m,即m=2n-1=7。按照算法思想(1),其存储结构HT的初始状态如图2所示图2 HT初始状态图步骤2:按照算法思想步骤(2)、(3)、(4),HT的终结状态如图3(a)所示(其中parent、lchild和rchild的值分别为结点在表中的序号)。图3 HT的终结状态图和树形步骤3:从叶子结点出发走一条从叶子结点到根路径便可求出每个字符的赫夫曼编码。以求解值为2(结点序号为2)的结点的赫夫曼编码为例:结点2是双亲结点5的左孩子,求得第一个编码为“0”;结点5是双亲结点6的右孩子,求得第二个编码为“1”;结点6是双亲结点7

5、的右孩子,求得第三个编码为“1”;结点7没有双亲,即结点7为根结点,整个赫夫曼编码求解完毕。因为,求解过程是自底向上的过程,因此,权值为2的结点的赫夫曼编码为110(是求解过程顺序得到的编码逆序)。最终得到的4个赫夫曼编码如图4所示图4 4个字符的赫夫曼编码及树型2.5算法设计(1)主程序模块void main() 初始化; while(“命令”= “继续”)接受命令;处理命令;(2)二叉树的存储结构表示typedef struct BiTNode char data; int weigh; struct BiTNode * lchild,*rchild;BiTNode,*BiTree;(3)

6、赫夫曼树的存储结构和赫夫曼编码的存储结构根据赫夫曼树的特点和操作特性,可以按图5所示的存储结构定义赫夫曼树。图5赫夫曼树和赫夫曼编码的存储结构具体算法描述如下:typedef struct unsigned int weigh; /根结点的权值 unsigned int parent,lchild,rchild; /双亲、左孩子和右孩子的序号HTNode,*HuffmanTree; /动态分配数组存储赫夫曼树Typedef char *HuffmanCode; /动态分配数组存储赫夫曼编码表(4)存储二叉树中的非空的权值非零的节点的结构typedef struct tempsave int w

7、eigh; char ch;tempsave,*temp;(5)最小权值的求解是在哈弗曼树中i个结点中找出权值最小的结点序号,相应的图如图所示图6查找个结点中最小权值结点序号的-图具体算法描述如下:int min(HuffmanTree t,int i) /求解最小权值的操作/初始条件:赫夫曼树已存在/操作结果:返回i个结点中权值最小树的根结点序号,被select()调用 int j,flag; unsigned int k=UINT_MAX; / 取k为不小于可能的值 for(j=1;j=i;j+) if(tj.weights2) j=s1; s1=s2; s2=j; 2.6程序设计思路2.

8、6.1功能模块图各模块之间的调用关系如下: 图 7功能模块图2.6.2功能模块思路设计(1)主程序模块(2)二叉树创建模块:实现二叉树的创建;从键盘建立二叉树采用先序遍历的顺序进行创建,并输入数据,由键盘输入每个节点的数据,当输入为“#”时,当前操作的节点指针为NULL,采用先左子树后右子树的顺序函数根据输入数据的形式,生成相应的二叉树结构。(3)查找非零节点模块:查找二叉树中非零节点,并存储其在一个数组中;(4)哈夫曼树模块:实现哈夫曼树的创建;(5)输出模块:输出创建的哈夫曼编码;(6)查找最小叶节点模块:查找非零叶节点中最小的两个。系统流程图如下:图8 系统流程图2.7 程序源代码#in

9、clude #include#include #include#include typedef struct unsigned int weight; unsigned int parent,lchild,rchild;HTNode,*HuffmanTree; / 动态分配数组存储赫夫曼树typedef char *HuffmanCode; / 动态分配数组存储赫夫曼编码表int min(HuffmanTree t,int i) /求解最小权值的操作/初始条件:赫夫曼树已存在/操作结果:返回i个结点中权值最小树的根结点序号,被select()调用 int j,flag; unsigned in

10、t k=UINT_MAX; / 取k为不小于可能的值 for(j=1;j=i;j+) if(tj.weights2) j=s1; s1=s2; s2=j; void HuffmanCoding(HuffmanTree &HT,HuffmanCode &HC,int *w,int n) int m,i,s1,s2,start;unsigned c,f; HuffmanTree p; char *cd; if(n=1) return; m=2*n-1; HT=(HuffmanTree)malloc(m+1)*sizeof(HTNode); for(p=HT+1,i=1;i=n;+i,+p,+w)

11、(*p).weight=*w; (*p).parent=0; (*p).lchild=0; (*p).rchild=0; for(;i=m;+i,+p) (*p).parent=0; for(i=n+1;i=m;+i) select(HT,i-1,s1,s2); HTs1.parent=HTs2.parent=i; HTi.lchild=s1; HTi.rchild=s2; HTi.weight=HTs1.weight+HTs2.weight; /从叶子到根逆向求每个字符的哈夫曼编码 HC=(HuffmanCode)malloc(n+1)*sizeof(char*); cd=(char*)ma

12、lloc(n*sizeof(char); cdn-1=0; for(i=1;i=n;i+) start=n-1; for(c=i,f=HTi.parent;f!=0;c=f,f=HTf.parent) if(HTf.lchild=c) cd-start=0; else cd-start=1; HCi=(char*)malloc(n-start)*sizeof(char); strcpy(HCi,&cdstart); free(cd); void main()printf(Huffman Tree Creating & Huffman Encoding, by ss1271.n);Huffman

13、Tree HT;HuffmanCode HC; int *w,n,i; printf(请输入权值的个数(需要大于1):); scanf(%d,&n); w=(int*)malloc(n*sizeof(int); printf(请依次输入%d个权值(整型,每输入完成一个请回车确认):n,n); for(i=0;i=n-1;i+) scanf(%d,w+i); HuffmanCoding(HT,HC,w,n); printf(哈夫曼编码结果为:n); for(i=1;i=n;i+) puts(HCi);3.运行结果分析在本程序中,建立赫夫曼树需要用户输入节点的个数及其对应的权值,结点限定为大于0的

14、整数,权值为不小于0的数。输入节点个数后按空格键在输入权值(每输入一个权值键一下回车),再按回车键进行下一步输入。演示程序以用户和计算机的对话方式执行,即在计算机终端上显示提示信息之后,由用户在键盘上输入程序要求的数据。输入完毕后显示运算结果。3.1运行结果及截图(1)运行程序,提示输入权值的个数(即结点的个数,需大于1),运行结果如图9所示图9提示输入权值个数(2)输入结点个数后,击回车键,提示输入各个结点的权值,每输入一个权值后回车确认,知道提示下步操作,运行结果如图10所示图10 键入权值数量(3)各个结点权值输入完毕后,回车确认,便会输出该树的赫夫曼编码,根据赫夫曼编码也可会出相应的赫

15、夫曼树,运行结果如图11所示图11输出赫夫曼树编码3.2 运行情况分析(1)在输入一个空树的情况下,程序给出提示,若用户想继续则输入y后按回车键,否则输入n后回车。(2)在输入树非空的情况下,程序会显示刚输入树的先序遍历结果,以及生成的赫夫曼树的先序遍历的结果 。其中每个节点组成为:节点名(权值,左孩子节点名,右孩子节点名)。 (3)算法的时空分析创建二叉树的算法createBiTree,查找非零节点的算法find以及打印赫夫曼树的算法print,都是遍历二叉树的操作。显然遍历二叉树的算法中的基本操作是访问节点,则不论按哪一种次序进行遍历,对含n个节点的二叉树,其时间复杂度均为O(n).所需辅

16、助空间为遍历过程中栈的最大容量,即树的深度,最坏情况下为n,则空间复杂读也为O(n)。4.设计体会这次设计我认为做的比较好的地方是清楚的将问题分为几个小的方面,用几个模块分别完成对应的功能,这样思路清晰,便于编写程序和调试。这是一个值得保持的好习惯。不好的一方面是对于生成的赫夫曼树缺乏一种简洁的表述,感觉自己的的表示方法有些繁琐。如果能够用打印的方法输出生成的赫夫曼树就比较好。通过本次课程设计,使我对赫夫曼树有了更深一步的了解。在C语言的使用方面也有了一定的提高,对函数的调用上也有进步,比如开始我想用函数返回一个数组,但总是通不过编译,后来一查资料,才知道C中不能直接返回一个数组,于是我改用返

17、回指向数组的指针,终于解决了问题。同时,以前的模糊的概念也清晰了些。比如以前以为只要想返回多个值,就可以用引用。但在调试程序的时候发现并不是所有类型都有引用,比如数组就没有。同时本程序还有一些不足之处,如初始化编码长时,在中途如果输入有误就得全部重输,这样非常不利于初始化很长的代码的输入,如果能够在出错时可以改正就好了。这个实验题巩固和加深了我所学的知识,令我对以后的学习更加有兴趣。我认为以后的实验题如果能够更贴近实际、贴进生活且难度适中就是最能激发学生学习兴趣的好实验题了。通过这次试验我也着实感受了一次编程的乐趣,从中学到了不少的知识,更牢固的掌握了专业技能。虽然都说“程序=数据结构+算法”

18、,但我在学习运用数据结构编程之前,并没能深刻体会到这一点,直到这次课程设计实践才真正体会到了这一点。以前使用C语言编程,只注重如何编写函数才能够完成所需要的功能,只凭单纯的意识和简单的语句来堆砌出一段程序。但现在在编写一个程序之前,自己能够综合考虑各种因素,这样,即使在完整的程序还没写出来前,心里就已经有了明确的原图了,这样无形中提高了自己编写的程序的质量。我还深刻的理解了数据结构的重要性,只有真正的理解这样定义数据类型的好处,才能用好这样一种数据结构,了解典型数据结构的性质非常有用的,它往往是编写程序的关键。总之,这次课程设计巩固了我对所学知识的理解,加深了对编写程序的兴趣。 5.参考文献

19、1 严蔚敏.数据结构 C语言M.北京: 清华大学出版社,2006.10: 118-1442 严蔚敏,陈文博.数据结构及应用算法教程M.北京:清华大学出版社,2003.6: 150-1733 吴艳,周苏,李益明等.数据结构与算法实验教程M.北京:科学出版社,2007.2: 169-1744 王立柱.c语言与数据结构M.北京:清华大学出版社,2005.5: 123-1455 谭浩强.c语言程序设计M.北京:清华大学出版社,1999.7: 137-1586 李春葆.数据结构(C语言篇)习题与解析M.北京:清华大学出版社,2000.2: 38-527 严蔚敏,吴伟民.数据结构(C语言版)、数据结构题集M.北京:清华大学出版社,2005.7: 28-408 夏克俭.数据结构+算法 M.北京:国防工业出版社,2001.2: 264-2719 徐孝凯.数据结构实用教程(C描述) .M.北京:清华大学出版社,2001 304-305

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

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