GESP6级C++考试语法知识(四、图与树(四))


第四课:《哈夫曼密码森林》

------ 哈夫曼树与压缩魔法的秘密


🌟故事开始:魔法卷轴不够用了!

1、在"二叉树进阶王国"毕业后,

同学们已经掌握了:

✅ 二叉树

✅ BST

✅ 完全二叉树

可是突然有一天!


2、🚨紧急事件发生了!

森林王国里的:

📜 魔法卷轴仓库

快装不下了!

因为:

魔法信件越来越多。


3、🌟问题来了!

比如一句魔法咒语:

复制代码
AAAAABBC

里面:

复制代码
A 出现5次
B 出现2次
C 出现1次

如果每个字符都用一样长的编码:

仓库会浪费很多空间!


4、大家着急地问:

"有没有办法让常见字符更短,"

"罕见字符稍微长一点呢?"

就在这时,

森林深处出现了一位计算机科学家:

🧙 哈夫曼先生


5、他说:

"孩子们,"

"欢迎来到------"

🌳《哈夫曼密码森林》🌳


第一章:什么是哈夫曼树?


1、🌟核心思想

哈夫曼树:

是一种:

🌟让总长度最短的树!


2、🌟一句话理解

出现次数多:

编码短。

出现次数少:

编码长。


3、🌟像什么?

像快递员送货。


4、🌟天天送的地方

放近一点。


5、🌟很少送的地方

远一点没关系。


🌟这样总路程最短!


第二章:为什么要压缩?

1、🌟普通编码的问题

假设:

复制代码
A = 001
B = 010
C = 011

每个字符:

都3位。


2、🌟但问题来了!

A特别多。

却和C一样长。

浪费空间!


3、🌟聪明办法

让:


🌟常见字符

短一点。


🌟少见字符

长一点。


4、🌟结果

总长度会大大减少!


第三章:哈夫曼树如何构造?


1、哈夫曼先生说:

"秘诀只有一句话!"


2、🌟每次选择最小两个合并!


🌟这是整节课最重要的话!


第四章:开始建树!


1、🌟例子

字符频率:

字符 出现次数
A 5
B 2
C 1
D 1

2、🌟第一步:找到最小两个

最小:

复制代码
C=1
D=1

3、🌟合并!

复制代码
   2
  / \
 C   D

新节点权值:

1+1=2


4、🌟现在剩下:

节点 权值
A 5
B 2
CD 2

5、🌟第二步

选最小两个:

复制代码
B=2
CD=2

6、🌟继续合并!

复制代码
      4
     / \
    B   2
       / \
      C   D

7、🌟第三步

剩下:

节点 权值
A 5
BCD 4

8、🌟最后合并!

复制代码
           9
         /   \
        4     A
       / \
      B   2
         / \
        C   D

9、🌟哈夫曼树完成!


第五章:哈夫曼编码


1、哈夫曼先生说:

"现在开始赋予密码!"

规则:


2、🌟向左走

记:

复制代码
0

3、🌟向右走

记:

复制代码
1

🌟开始编码!


1、🌟A

路径:

复制代码

编码:

复制代码
1

2、🌟B

路径:

复制代码
左 左

编码:

复制代码
00

3、🌟C

路径:

复制代码
左 右 左

编码:

复制代码
010

4、🌟D

路径:

复制代码
左 右 右

编码:

复制代码
011

5、🌟发现了吗?


(1)🌟A最常见

所以:

编码最短!


(2)🌟C、D很少见

所以:

编码长一点。


6、🌟这就是压缩的秘密!


7、🌟哈夫曼编码可能是不唯一的,但最终的压缩效果(总位数)一定相同。


第六章:为什么哈夫曼树最优?


1、同学们问:

"为什么哈夫曼编码一定是最省呢?"


2、🌟因为:

频率大的节点:

离根更近。


3、🌟频率小的节点:

放深一点。


4、🌟于是:

总路径最短!


5、🌟核心公式(理解即可)

总长度:

(频率×编码长度)


6、🌟目标:

让这个值最小!


第七章:优先队列登场!


1、汉克老师说:

"每次都找最小两个,"

"手找太慢了!"

于是:

一种神奇工具出现了:

🌟priority_queue


2、🌟作用

自动帮你找到最小值!


3、🌟像什么?

像:

自动排序宝箱。


4、🌟放进去

复制代码
5 2 1 1

🌟每次自动弹出最小!

复制代码
1
1

5、🌟这太适合哈夫曼树了!


第八章:哈夫曼树代码(启蒙版)


1🌟定义:

复制代码
priority_queue<int,
               vector<int>,
               greater<int>> q;

2、🌟作用

建立:

小根堆

最小值永远在最前面。


3、🌟加入数字

复制代码
q.push(5);
q.push(2);
q.push(1);
q.push(1);

4、🌟取最小

复制代码
int a=q.top();
q.pop();

5、🌟哈夫曼核心循环

复制代码
while(q.size()>1)
{
    int a=q.top(); q.pop();
    int b=q.top(); q.pop();

    q.push(a+b);
}

6、🌟详细讲解


(1)每次取两个最小


(2)合并

a+b


(3)再放回去


(4)🌟直到只剩一个!

哈夫曼树完成!


第九章:经典例题


1、🌟题目

数字:

复制代码
1 2 3 4

每次合并最小两个。

求总代价。


2、🌟第一步

复制代码
1+2=3

目前总代价为:

复制代码
3

3、🌟剩下

复制代码
3 3 4

4、🌟第二步

复制代码
3+3=6

5、目前总代价为:

3+6=9


6、🌟剩下

复制代码
4 6

7、🌟第三步

复制代码
4+6=10

8、最终总代价为:

9+10=19


9、🌟答案

复制代码
19

10🌟这类题:

CSP经常考,选择题考的几率大!


第十章:举一反三!


1、🌟哈夫曼树能干什么?


🌳文件压缩

🌳图片压缩

🌳音乐压缩

🌳视频压缩


2、🌟原来:

我们每天都在使用哈夫曼思想!


第十一章:课堂训练


🌟训练1

频率:

复制代码
A=3
B=2
C=1
D=4
E=1

请构造哈夫曼树。


🌟训练2

写出这个哈夫曼树的编码。


🌟训练3

求这个哈夫曼树合并的总代价。


第十二章:整个树课程大总结


🌟第一课

图与树:

✅ 图

✅ 树

✅ DFS


🌟第二课

二叉树:

✅ 前序

✅ 中序

✅ 后序

✅ 递归


🌟第三课

进阶树:

✅ 完全二叉树

✅ BST

✅ 数组存树


🌟第四课

哈夫曼树:

✅ 贪心思想

✅ priority_queue

✅ 压缩编码


🌟现在我们已经掌握:


🌳树的基础世界!


我们再回想下列问题:

⚔️问题1

为什么哈夫曼树:

总是优先合并最小两个?


⚔️问题2

为什么 BST 中序遍历一定有序?


⚔️问题3

完全二叉树为什么适合数组存储?


⚔️问题4

DFS 为什么像走迷宫?


🌟汉克老师最后说:

"真正厉害的算法高手,"

"不是背代码的人。"

"而是能把复杂问题,"

"变成一棵知识树的人!" 🌳

相关推荐
子兮曰2 小时前
whisper.cpp 深度解析:从边缘设备到实时语音识别
前端·c++·后端
特种加菲猫2 小时前
二叉搜索树:数据世界的“快速寻路指南”
开发语言·c++
naturerun2 小时前
从数组中删除元素的算法
数据结构·c++·算法
特种加菲猫2 小时前
STL关联容器:Set/Multiset与Map/Multimap详解
开发语言·c++
Andy2 小时前
C++ list容器基本逻辑结构详解
c++·windows·list
想唱rap3 小时前
传输层协议TCP
linux·运维·服务器·网络·c++·tcp/ip
瑶池酒剑仙4 小时前
C++类和对象完全指南:从封装继承多态到内存布局的面向对象宝典(雨夜论道)
c语言·开发语言·c++·visual studio
潇湘散客5 小时前
CAX软件插件化设计实现牛刀小试
c++·算法·图形学·opengl
Ricky_Theseus5 小时前
const 和 #define 的区别
c++