| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 数据结构与算法 -> 数据压缩中的编码问题---堆生成哈夫曼树 -> 正文阅读 |
|
[数据结构与算法]数据压缩中的编码问题---堆生成哈夫曼树 |
Description ZC一天在看计算机的书籍的时候,看到了一个有趣的东西!每一串字符都可以被编码成一些数字来储存信息,但是不同的编码方式得到的储存空间是不一样的!所以ZC 就想是否有一种方式是可以得到字符编码最小的空间值!显然这是可以的,因为书上有这一块内容--哈夫曼编码(Huffman Coding);一个字母的权值等于该字母在字符串中出现的频率。所以ZC 想让你帮忙,给你一串个字符串,并让你判断这个字符串编码之后的空间值(即01串的长度)? Input 第一行是一个数字n,表示有n组数据,然后每一组数据是一串字符串(没有空格只有包含小写字母组成,长度不超过100). Output 对于每组测试数据输出这个串编码之后的空间值。 Sample Input 2 aaabbbb aaabbbbccccc 这一题在问最小的01串长度。对于每一个字符用01进行编码,这时候我们一定会想让出现频率高的编码长度短一点?,那么怎么样安排可以让最终的总长度最短,这其实就是构造一棵哈夫曼树然后求叶子路径长度的问题。 首先先要对输入进行简单处理,先将每个字符串出现的次数统计好。这里我用了桶实现,因为只有小写字母,只要放先把字符放进26个桶里然后再取出来就可以统计每个字符的频率。 接下来就是哈夫曼树的构造。 哈夫曼树的构造规则就是每次从有效区间里面找出两个最小的树合成一棵树再放进原来的队伍中,这里用优先队列可以比较快实现。为了练习数据结构,这里采用堆这种数据结构来实现,用模拟链表来实现类似于树的构造。 定义树的权值是叶子结点权值的总和,叶子结点也就是我们的字符频率,有效区间是建哈夫曼树的考虑区间。我们每次会在有效区间内取出两课权值最小的树,然后合成一个大树放回队伍中,大树的权值就是两棵树的权值相加,接下来取出的这两棵树就不会再被用到了,被纳入无效区间,也就是删除。 举个例子,比如aabbc,统计得到a2b2c1,那么就是要对122进行哈夫曼树的构造。 如下图 初始是三个数字1 1 2,接下来找出最小也就是1和2两个合成3 然后再把3插入有效区间内,?12扔进无效区间内,如下图 ?接下来我们在游戏掉区间内找两个最小合成,重复这样的操作我们就能得到这样的一棵哈夫曼树 ?下面是如何用堆来实现这个过程 假设有len个节点,每次的合成都是找出两个最小的合成一个比较大的,那么也就是一次会减少一个节点,所以要进行len-1轮合成,会多出lenn-1个节点,所以建立一个2*len-1的数组来存放所有涉及到的节点。 对于每个节点,我们需要存储的是这个节点的权值,叶子节点存的也就是字符的频率,对于左子树和右子树,这里用的是模拟链表,所以存放的是左右子树节点下标在数组中的位置,叶子结点存0,也就是空。
先做好堆排序,也就是数组输入,然后调整为小根堆。
对于每一轮,先把一个最小的放到最后,然后把有效区间的最后一个放到第一个,顶替删除的最小节点,然后再次调整为小根堆(堆的删除操作),重复前面的操作,取出一个最小的放到最后,然后再用有效区的最后一个顶替第一个,调整为小根堆,这时候再用两个取出来的两棵树合成一课树,插在有效区最后(堆的插入操作),然后将大树的左右孩子指向合成这两棵树的节点下标,一轮就完成了。 如下图所示,n=3,所有最终会有2+3=5个节点,先开辟号位置,分界线代表有效区,开始指向3。先找出1,然后放到最后,这时候2顶替1,调整,有效区左移,再来一轮2放到最后,有效区左移,2到堆顶,然后两个出来的节点1和2合成3,让节点指向合成他的节点,然后插入到堆中,完成一轮。 一轮操作代码如下 ?m是总长度,len是有效区间的长度,也就是1---len是建哈夫曼树的考虑区间
到最后一定是第一个是整个哈夫曼树的根节点,然后因为要计算编码总长度,其实就是计算叶子结点路径长度的问题,而路径长度也可以理解为深度,这里运用递归来求解。 也就是如果判断为叶子结点,那么答案加上此时对应的深度。
?最后是完整代码
? ? |
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/25 23:33:41- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |