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

加入VIP,免费下载
 

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

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

下载须知

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

版权提示 | 免责声明

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

c++数据结构实验哈夫曼树.docx

1、c+数据结构实验哈夫曼树数据结构实验报告1实验要求i.实验目的:(1)掌握二叉树基本操作的实现方法(2)掌握二叉树基本操作的实现方法(3)了解哈夫曼树的思想和相关概念(4)学习使用二叉树解决实际问题的能力(5)熟悉C+语言的基本编程方法,掌握集成编译环境的调试方法,熟练改错方 法。(6)熟悉设计算法的过程(7)进一步掌握指针、异常处理的使用ii.实验容:利用二叉树结构实现赫夫曼编/解码器。基本要求:1、初始化(Init):能够对输入的任意长度的字符串s进行统计,统计每个字符的频度,并建立赫夫曼树2、建立编码表(CreateTable):利用已经建好的赫夫曼树进行编码,并将每个字符的编码输出。3

2、、编码(Encoding):根据编码表对输入的字符串进行编码,并将编码后的字符串输出。4、译码(Decoding):利用已经建好的赫夫曼树对编码后的字符串进行译码,并输出译码结果。5、打印(Print):以直观的方式打印赫夫曼树(选作)6、计算输入的字符串编码前和编码后的长度,并进行分析,讨论赫夫曼编码的压缩效果。测试数据: I love data Structure, I love Computer.I will try my best to study data structure. 提示: 1、用户界面可以设计为“菜单”方式:能够进行交互。 2、根据输入的字符串中每个字符出现的次数统计频

3、度,对没有出现的 字符一律不用编码。iii.代码要求:1、必须要有异常处理,比如删除空链表时需要抛出异常;2、保持良好的编程的风格:代码段与段之间要有空行和缩近标识符名称应该与其代表的意义一致函数名之前应该添加注释说明该函数的功能关键代码应说明其功能 3、递归程序注意调用的过程,防止栈溢出2. 程序分析树形结构是一种非线性结构可以用结点之间的分支来表示层次关系,二叉树是每个结点最多两个子树的有序树,十分适合计算机处理问题,而哈夫曼树是一种特殊的二叉树,它将权值大的数据放在了离根较近的结点处,这样使得带权路径长度最短,是非常好的存储方式。2.1 存储结构1.结点结构的存储方式:根(下面结点的父结

4、点)结点:左孩子 右孩子 struct hnode /哈夫曼树结点的结构体 int weight; int parent; int lchild; int rchild; char data;结点存储示意图:int weightint parentint lchildint rchildchar data2.编码表的实现中使用了以下结构体:Struct hcode /编码表结构体 char data; /字符 char code100; /编码容;示意图为:char datachar code1003.在select函数中使用的结构体:struct node int num; char dat

5、a;int numchar data2.2关键算法分析: A)Init初始化:统计需要编码的字符串中每个字符的频度并建立哈夫曼树实现:在函数中设置了一个数组type用来统计字符串中字符的类型,no数组则用于统计每种字符串的个数,count用于存储每类字符的相应的个数。void Huffman:Init() /将输入的数据保存至类中 cout 请输入需要编译压缩的容 endl; cin.getline(in, 500, n); n = 0; no = 0; count = new node127; /type for (int j = 0; j 127; j+) /对每一种字符的个数进行初始化

6、countj.num = 0; while (inno != 0) /结束之前,每输入一个字符,则对应的数目增1 +countinno.num; countinno.data = inno; +no; for (int k = 0; k0) n+; cout countk.data countk.num endl; 将初始化的数据用于建立哈夫曼树:void Huffman:createht() no = 0; htree = new hnode2 * n - 1;/含有n种字符的哈夫曼树需要2*n-1个结点 for (int i = 0; in; i+) while (countno.num

7、= 0) /该字符没有出现,跳过,继续找出现过的字符 no+; htreei.weight = countno.num; /将count里统计的次数传入哈夫曼树的节点中,作为字符权重 htreei.lchild = -1; htreei.rchild = -1; htreei.parent = -1; /将左右孩子结点和父节点都置空 htreei.data = countno.data; /将字符传入哈夫曼树的结点 no+; int x = -1, y = -1; for (int i = n; i 2 * n - 1; i+) SelectMin(x, y, i); /挑选三者中的权重较小的

8、两个 htreex.parent = htreey.parent = i; /令较小的x、y为孩子节点,该两个结点的父节点是i htreei.weight = htreex.weight + htreey.weight;/i结点字符的权重赋为是左右孩子字符权重之和 htreei.lchild = x; /左孩子为x htreei.rchild = y; /右孩子为y htreei.parent = -1; /父节点置空 x = -1; y = -1; 注意select函数的编写十分重要,必须成功选出每次权值最小的两个数据才能正确的建立哈夫曼树void Huffman:SelectMin(int

9、 &x, int &y, int k) /选出权值较小的两个字符结点 int i = 0; while (i k) while (i k&htreei.parent = -1) /当前结点不具有父结点且满足ik则进行循环 if (x = -1) /左孩子 x = i; else if (y = -1) y = i; else if (htreex.weight = htreey.weight) if (htreey.weight htreey.weight) if (htreei.weight = htreex.weight) x = x; y = y; else x = i; i+; i+;

10、 B)create table建立编码表:利用初始化得到的结果将哈夫曼树进行编码并输出每个字符的编码。1.在程序中设置了一个数组save来存储每个字符的编码。void Huffman:createhc() /建立哈夫曼编码表 hcodetable = new hcoden; /生成编码表 for (int i = 0; in; i+) hcodetablei.data = htreei.data; int child = i; int parent = htreei.parent; int k = 0; while (parent != -1) if (child = htreeparent.

11、lchild) /该节点是父节点的左孩子则编码为0,右孩子则编码为1 hcodetablei.codek = 0; else hcodetablei.codek = 1; k+; child = parent; /将该节点的父节点进行编码输出 parent = htreechild.parent; hcodetablei.codek = 0; /code数组以0结尾 Reverse(hcodetablei.code); /逆置输出字符的编码值 cout 每个字符的编码为: endl; for (int i = 0; in; i+) cout hcodetablei.data : hcodeta

12、blei.code = 0) /通过t数组将use数组的数据逆序排序 usej = ti; i-; j+; usej = 0;C).Encoding根据编码表对输入的字符串进行编码,并将编码后的字符串进行输出。 void Huffman:Encoding() /编译输入容为代码容用0和1表示 cout 编码结果为:; int k = 0; for (int i = 0; ini != 0; i+) int j = 0; while (hcodetablej.data != ini) /编码表的字符等于输入容的字符时进行下一个while循环 j+; int m = 0; while (hcode

13、tablej.codem != 0)/输出该字符的编码 savek = hcodetablej.codem;/save数组记录编码数据 cout savek endl; k+; m+; savek = 0; cout endl;D).Decoding译码:利用建好的哈夫曼树对编码后的字符串进行译码,并输出译码的结果。void Huffman:Decoding() cout 解码结果为:; int i = 0, j = 0; while (savei != 0) int child = 2 * n - 1 - 1;/找到保存根节点的数组数 while (htreechild.lchild !=

14、-1)/若是这个节点父节点的孩子存在则继续向下寻找 if (savei = 0) child = htreechild.lchild; /是0则找左孩子 else child = htreechild.rchild; /是1则找右孩子 i+; cj = hcodetablechild.data; /若不存在孩子节点,则令数组的元素为该节点的字符变量 cout cj; j+; /逐个输出字符容 E).print打印:以直观的方式打印哈夫曼树通过递归调用从根结点开始以中序遍历的方式打印出树void Huffman:printtree(int qi, int f) if (htreeqi.lchil

15、d != -1) printtree(htreeqi.lchild, f + 4); cout setw(f); if (qi n) cout hcodetableqi.data endl; else cout htreeqi.weight endl; if (htreeqi.rchild != -1) printtree(htreeqi.rchild, f + 4);F).计算输入输出前后编码长度并进行分析讨论压缩效果int Huffman:getsizea() return strlen(in);int Huffman:getsizeb() return strlen(save);(b -

16、 a)即为所求。2.3 其他1.哈夫曼树的类:class Huffmanprivate: hnode*htree; /哈夫曼树 hcode*hcodetable; /哈夫曼编码表 char c127; /字符类型 node*count; /记录各个字符及其出现次数 int n; /输入字符的种类的个数 int no; /输入字符的个数 char in500; /保存输入的字符串 char save500; /记录所有输入容被编码后的结果public: void createht(); /创建哈夫曼树 void createhc(); /创建编码表 void Init(); /初始化 void

17、Encoding(); /编码 void Decoding(); /解码 void SelectMin(int &x, int &y, int k);/求最小权重的字符 int getsizea(); int getsizeb(); void printtree(int qi, int f); /打印哈夫曼树; int getn(); Huffman();2.switch语句:switch (choice) case 1: ht.Init(); break; case 2: ht.Encoding(); break; case 3: ht.Decoding(); break; case 4:

18、ht.printtree(2*qi-1-1,f); break; case 5: cout 压缩前 b bit 压缩后 a bit endl; cout 压缩了 (b - a) 个bit endl; break;default: break; 3.计算时间复杂度:A) o(n);B)o(n);C) o(n);D)o(n);E) o(n);F)o(1);3. 程序运行结果1.程序流程图: 否 是 2.测试条件:输入字符串的长度小于500;3.测试结论:4. 总结在这次实验中我通过不断的调试,理解了树的结构与哈夫曼树编解码的代码,并且回忆了上学期c+中学习到的知识,编写了select和revers

19、e函数,在编程过程中出了许多错误:1.是在switch语句中赋值,经过程序提示改为了在主函数中赋值void main() Huffman ht; ht.Init(); ht.createht(); ht.createhc(); ht.Encoding(); ht.Decoding(); int f = 0; int qi = ht.getn(); int a = ht.getsizea(); int b = ht.getsizeb(); menu(); int choice = 1; for (int p = 0; p choice; switch (choice) case 1: ht.In

20、it(); break; case 2: ht.Encoding(); break; case 3: ht.Decoding(); break; case 4: ht.printtree(2*qi-1-1,f); break; case 5: cout 压缩前 b bit 压缩后 a bit endl; cout 压缩了 (b - a) 个bit endl; break; 2.因为粗心还直接用主函数中的函数直接调用类的私有成员,这样的错误实在不应该,后面通过类对象调用类的共有函数而实现了对数据成员的操作。3.Print tree的过程比较需要使用递归函数,在调试中回忆了相应的知识。整体而言,虽然花费了大量的时间,但是收获也很丰富,程序比较长下一步需要化简处理,使代码更为灵活生动

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

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