算法C++ 哈夫曼树与哈夫曼编码算法理解+示例习题(第五章)


前引


这应该是倒数第二篇关于算法的了
现在想想算法这本书就快要走到尽头了 我也是不知道之前我怎么慢慢坚持把整本书大部分的内容都记录了下来 并写了绝大部分的代码实现的

关于哈夫曼树 我的记忆特别特别清楚
就是做了浙大数据结构中的一道题 叫做Huffman Codes
相关我的习题博客链接 和关于哈夫曼树习题的链接我放在最底下面
如果有想要完全挑战一下自己的可以尝试做一下 浙大的哈夫曼树的题
我反正记得我做了可能有个整两天左右哈哈哈哈哈 就是完全从头开始做
真的做了超级久超级久 到现在竟然哈夫曼树大概是什么都忘记了

就着现在对算法进行个总结 我也顺带回忆回忆大概的内容吧


浙大数据结构讲解哈夫曼树视频链接

哈夫曼树和哈夫曼编码 浙大数据结构(中国大学Mooc)



我的理解


哈夫曼树存在的意义

比如我们记录数据用的是树来记录
那我们就假设把数据随意放位置
那当我们在树中寻找那些数据时 那是不是会出现有些数据我们查找频率会很多 有些又相对会很少
比如一些常用的数据 我们查找频率相对就高的多

ok 那这个时候我们来计算一下每次调用查找的成本了
假设 我们把我们最经常调用的数据 放到了树的最底下 也就是叶节点位置
那当我们查找的时候 是不是每次都要把整个树的高度的数据遍历一次
我们才能走到树的最底下
相反 如果我们把数据放到最顶上面 很显然 每次我们一调用查找就ok了

那么此时哈夫曼树就为此诞生了
我们针对不同权值的节点 放到不同的位置就ok了
那哈夫曼树干嘛呢
就是使我们WPL最小 WPL是树的所有叶结点的带权路径长度之和
用通俗点的话 意义来讲 就是可以使我们的数据总调用查找的成本最小
我是这个样子理解的


哈夫曼编码存在的意义


我是这样理解的(水平有限 仅用自己的话来表达)
就是比如 我们用固定的二进制编码8位来记录字符
比如我们记录一共10000个字符 那么一共就需要8w位
那么如果记录1亿个字符 那么一共就需要8亿位

很显然 8位很多时候是不够的
但是对于每一个字符来说 有些字符很小 那么剩下的位对于他来说就是铁浪费
但是对于有些字符来说 是比较合适的
那么我们就可以计算一下空间利用率
如果字符中存在非常多的ascii或unicode很小的字符
而只出现很少很少的"大"字符的情况
那么空间浪费是不是就特别的吓人了

所以针对这种情况 一种编码形式就出现了


如何构建哈夫曼树


我们可以通过 最小堆来实现
具体的实现步骤大家可以看看视频链接了解一下
这里我就简单概括一下
哈夫曼树就是把 序列节点中最小的两个权值点合并变成一棵树
父节点的值就是两个子节点的权值之和
我们又把父节点的值放到序列中 继续进行合并
直到合并到只有一个权值

那么我们如何在序列中挑选两个权值最小的节点呢
用C++的STL库 我们可以使用priority_queue优先队列
那么c语言的话 我们只能自己造一个最小堆了
最小堆的基本操作 什么插入 删除 如果不是很清楚的话
也可以看一下我的博客 专门写了最小堆的操作的

好像是最大堆 但是思想是一样的
算法C++ 优先队列 堆排序大顶堆代码实现(第二章)


哈夫曼编码构建


既然我们把树都建立好了
编码怎么编呢 下面一张图就表示了
具体就是用 0-1编码
如果子节点在右边的话 就是1 子节点在左边的就是0

在这里插入图片描述

这样既能保证 不出现二重性 一个字符只有一串编码
而且又能使 字符的节省空间率大大增加
相比较 我们一个字符固定字符数
节省空间率那肯定大大增加


哈夫曼树习题+习题博客链接


需要注册pta账号 注册十分简单
7-9 Huffman Codes (30 分)

Huffman Codes (30分) 浙大数据结构讲解

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Love 6

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值