北京邮电大学信息与通信工程学院
数据结构实验报告
1.实验要求
利用二叉树结构实现哈编/解码器。
基本要求:
1、初始化(Init):能够对输入的任意长度的字符串s进行统计,统计每个字符的频
度,并建立哈
2、建立编码表(CreateTable):利用已经建好的哈进行编码,并将每个字符的
编码输出。
3、编码(Encoding):根据编码表对输入的字符串进行编码,并将编码后的字符串输
4、译码(Decoding):利用已经建好的哈对编码后的字符串进行译码,并输出
译码结果。
5、打印(Print):以直观的方式打印哈(选作)
计算输入的字符串编码前和编码后的长度,并进行分析,讨论哈编码的压缩效果。并用IlovedataStructure,IloveComputer。IwilltrymybesttostudydataStructure.进行测试。
2.程序分析
哈结点的存储结构包括双亲域parent,左子树lchild,右子树rchild,还有字符word,权重weight,编码code
对用户输入的信息进行统计,将每个字符作为哈的叶子结点。统计每个字符出现的次数作为叶子的权重,统计次数可以根据每个字符不同的ASCII码,根据叶子结点的权重建立一个哈。
建立每个叶子的编码从根结点开始,规定通往左子树路径记为0,通往右子树路径记为
1。由于编码要求从根结点开始,所以需要前序遍历哈,故编码过程是以前序遍历二叉树为基础的。同时注意递归函数中能否直接对结点的编码域进行操作。
编码信息只要遍历字符串中每个字符,从哈中找到相应的叶子结点,取得相应的编码。最后再将所有找到的编码连接起来即可。
译码则是将编码串从左到右逐位判别,直到确定一个字符。这就是哈的逆过程。遍历编码串,从哈中找到相应的叶子结点,取得相应的字符再将找到的字符连接起来即可。
2.1存储结构
哈结点存储结构
2.2关键算法分析
北京邮电大学信息与通信工程学院
1.统计字符频度
自然语言描述:
(1)取出字符串中的一个字符
(2)遍历所有初始化的哈结点
(3)如果结点中有记录代表的字符且字符等于取出的字符,说明该字符的叶子存在,则
将该结点的权值加1
(4)如果所有结点记录的字符均没有与取出的字符一致,说明该字符的叶子不存在,则
将结点的字符记为取出字符,并将权重设为1
(5)重复以上步骤,直至字符串中所有字符全部遍历
伪代码描述:
XXX(inti=0;i 1.1for(intj=0;j 时间复杂度O(n2),空间复杂度S(0) 2.构造哈 自然语言描述: (1)选出权值最小的两个结点,其权值和作为其根结点的权值,最小的结点作为左子树, 次小的作为右子树,不断将两棵子树合并为一棵树。 (2)重复上述过程,直至所有结点全被遍历完 伪代码描述: XXX; XXX(intj=n;j<2n-1;j++) 2.1intj1=0;intj2=0;2.2Select(HuffTree,leaves,j,j1,j2);/选出两个权值最小结点2.3HuffTree[j1].parent=j;HuffTree[j2].parent=j; 2.4HuffTree[j].weight=HuffTree[j1].weight+HuffTree[j2].weight;/根结点权值等于两个结点权值和 北京邮电大学信息与通信工程学院 2.5HuffTree[j].lchild=j1;HuffTree[j].rchild=j2;/左子树为权值最小,右子树权值次小 2.6叶子数--; 时间复杂度O(n),空间复杂度S(2) 3.为每个叶子结点编码 自然语言描述: (1)初始化一个字符数组Code暂存每个叶子结点的编码。 (2)前序遍历哈 (3)若结点左右子树都为-1,则将code复制到编码的code串,准备返回上一层,编码相 应少一位,code长度减1,返回 (4)否则按照从左到右的顺序前序遍历根结点的所有子树 (5)若访问左子树,则进入下一层,编码相应多一位,code长度加1并将最后一位赋0; 访问右子树,进入下一层,code长度加1并将最后一位赋为0 伪代码描述: XXX结点左右孩子均为-1 1.1.将Code复制到huffTree的XXX;1.3.否则1.3.XXX结点左子树存在XXX长度增一XXX最后一位赋0;1.3.1.3.访问左子树;1.3.1.4.层数减一;XXX结点右子树存在XXX长度增一XXX最后一位赋1;1.3.2.3.访问右子树;1.3.2.4.层数减一; 算法时间复杂度O(n2),空间复杂度S(60) 4.编码 自然语言描述: (1)定义字符串CodeStr储存编码 (2)遍历输入字符串的每一个字符 (3)对每一个字符,将其与HuffTree前n个叶子结点的word逐个比较,相同则将该结 点的编码串code连接到CodeStr的末尾 (4)遍历结束后,输出CodeStr 伪代码描述: XXX(字符串字符不为0) 1.1while(叶子结点word不为空) 1.1.1if(字符等于word中的字符) 1.1.1.1strcat(CodeStr,code); XXX; XXX< 北京邮电大学信息与通信工程学院 算法时间复杂度O(n) ,空间复杂度S(2) 5.译码 自然语言描述: (1)从编码串CodeStr的第一个字符开始与HuffTree第一个结点的编码域第一个字符比 (2)相等则继续比较后面的字符 (3)否则,从CodeStr第一个字符与HuffTree第二个结点的编码比较 (4)重复上述过程,将CodeStr中的所有字符比较完毕 伪代码描述: 1.在CodeStr和XXX中设比较的起始下标i和j 2.遍历数组huffTree 2.1.循环至CodeStr或XXX全部的字符均比较完 2.1.1.如果CodeStr[i]=huffTree[k].code,继续比较下一个字符,否则 2.1.2.将i和j回溯,跳出该层循环 2.2如果huffTree[k].code全比较完,输出huffTree[k].word。否则取huffTree下一个结点继续循环 时间复杂度O(n2),空间复杂度S(3) 3.程序运行结果 北京邮电大学信息与通信工程学院 测试条件:问题规模n的数量级为1。 测试内容:IlovedataStructure,IloveComputer.IwilltrymybesttostudydataStructure. 测试结论:测试的功能有:建立哈、对每个字符进行编码、对信息字符串进行编码、 对编码串进行译码,重新进行编码。各项功能均能正常运行。界面的跳转也能实 编码前信息总长度为6bits,编码后的长度为339bits。由于哈编码采用不等长编码,有效缩短了编码长度,节省了空间。 4.总结 调试时出现的问题及解决的方法 递归函数中的参数传递 在给每个字符编码时,由于编码是从根结点开始,所以选用与前序遍历相似的递归遍历形式。其中需要一个字符型数组来记录路径和编码,由于递归一次才有一位编码,所以这个数组也要随着递归函数的进行而不断修改。开始时我没有用指针最为参数而是直接将数组作为参数,结果发现每次调用递归函数时数组都是空。原来我用的是值传递,数组就算修改了也无法返回。这提醒了我之后运用递归函数时如果需要某个变量随函数递归而修改时应该使用地址传递而非值传递。 因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- 69lv.com 版权所有 湘ICP备2023021910号-1
违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务