数据结构题:根据所给权值设计相应的哈夫曼树,并设计哈夫曼编码

简介: 数据结构题:根据所给权值设计相应的哈夫曼树,并设计哈夫曼编码

前言


在数据结构树的这章中,常常有题目,是这样的“给定一组权值…,试设计相应的哈夫曼树”,有的还要求其带权路径长度,还有的是给定字符以及其使用频率,要求设计一个哈夫曼编码,同时要求设计哈夫曼树等等。

为此这种题的步骤解法,我将做详细的讲解,本文介绍两种题型,分别是求哈夫曼树以及设计哈夫曼编码,希望对阅读本博客以及有需要的小伙伴有用,如有错误不当之处,欢迎大佬们指正!

(😊😊😊)


提示:以下是本篇文章正文内容,下面案例可供参考。


一、涉及到的知识点


哈夫曼树:给定n个权值作为n个叶子结点,构造一棵二叉树,若该树的带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树,可以说,哈夫曼树是一种特殊的二叉树,这种树的所有的叶子结点都有权值,从而构造出带权路径长度最短的二叉树,其中权值较大的结点离根较近。

路径长度:树中路径上的分支数目。

树的路径长度:根结点到树中每个结点的路径长度之和。

叶子结点的权值:权值是人们根据需要为每个叶子结点赋予的一个数值。

叶子结点的带权路径长度:树根到一个叶子结点之间的路径长度与该结点权值的乘积。

树的带权路径长度:树中所有叶子结点的权值乘以该结点的路径长度之和,公式如下:

1666883888365.jpg

其中,Wk为第k个叶子结点的权值,Lk是从根结点到第k个叶子结点的路径长度。

哈夫曼编码:树中从根到每个叶子都有一条路径, 对路径上的各分枝约定指向左子树根的分枝表示“ 0 ” 码, 指向右子树的分枝表示“ 1 ” 码, 取每条路径上的“ 0 ” 或“ 1 ” 的序列作为和各个叶子对应的字符的编码, 这就是哈夫曼编码。


好接下来,我们了解了基本知识后,来看看这两道题简单的巩固一下

e.g.

1、求下图中二叉树的带权路径长度

1666883903457.jpg

解:结果如下:

WPL=2×2+3×2+4×2+6×2=30

2、写出下图哈夫曼树中D和F的哈夫曼编码(提示:哈夫曼树的每个左分支设为0,右分支设为1)

1666883936208.jpg

解:D和F的哈夫曼编码为

D:00

F:10


接下来,我们一起进入正题部分,两道例题了解一下😎


二、例题讲解


1、例题1


给定权值{5,10,12,15,30,40},构造相应的哈夫曼树(要求写出构造步骤),并求出该树的带权路径长度。(提示:哈夫曼树的每个左分支设为0,右分支设为1,要求同层中叶子结点权值从左到右,从小到大)。


解:注:只要将最小的两个权值合并, 合并后的值再入列中(最小的两个出列), 直至列中只有一个值结束。

按权值大小排列后得: {5,10,12,15,30,40},

取5和10,得到5+10=15,

从{12,15,15,30,40}找两个最小的12+15=27

{15,27,30,40}中取15+27=42

{30,40,42}中取30+40=70

{42,70}中取42+70=112

{112}停止。


因为要求同层中叶子结点权值从左到右,从小到大,即分别建立左右分支,不懂的小伙伴可以仔细看一下上述过程以及画的图,另题目要求在哈夫曼树的每个左分支设为0,右分支设为1。

则哈夫曼树如下:

1666883978264.jpg

带权路径长度:

(5+10+12+15)×3+(30+40)×2=266

提示:哈夫曼树中黄荧光笔标记处,画图中不用标出,为读者方便理解特注,即算这些所标记的叶子。


具体步骤图例:

1666883989808.jpg

1666883999421.jpg

1666884006517.jpg

1666884019107.jpg




2、例题2


已知一个电文字符集中有8个字符{A,B,C,D,E,F,G,H},它们使用的频率为{0.04,0.21,0.06,0.07,0.15,0.18,0.12,0.03},设计一个哈夫曼编码。(提示:哈夫曼树的每个分支左分支设为0,右分支设为1,要求同层中叶子结点权值从左到右,从小到大)。

解:将使用的频率乘以100,得到它们的权值

乘以100,得:{4,21,6,7,15,18,12,3},

按大小排序后,{3,4,6,7,12,15,18,21}

取3和4,得3+4=7,

从{6,7,7,12,15,18,21}中取6+7=13

{7,12,13,15,18,21}中取7+12=19

{13,15,18,19,21}中取13+15=28

{18,19,21,28}中取18+19=37

{21,28,37}中取21+28=49

{37,49}中取37+49=86

{86}停止

则哈夫曼树如下:

1666884035141.jpg

由哈夫曼树得到哈夫曼编码为(由上至下编码):

A:0101

B: 10

C: 1100

D: 1101

E:111

F: 00

G:011

H:0100


总结


以上就是全部内容,本文简单介绍了哈夫曼树的一些基本知识和如何求哈夫曼树以及如何设计哈夫曼编码的方法,希望能给读者带来帮助。


相关文章
|
8月前
|
存储 C++
【C++数据结构——树】哈夫曼树(头歌实践教学平台习题) 【合集】
【数据结构——树】哈夫曼树(头歌实践教学平台习题)【合集】目录 任务描述 相关知识 测试说明 我的通关代码: 测试结果:任务描述 本关任务:编写一个程序构建哈夫曼树和生成哈夫曼编码。 相关知识 为了完成本关任务,你需要掌握: 1.如何构建哈夫曼树, 2.如何生成哈夫曼编码。 测试说明 平台会对你编写的代码进行测试: 测试输入: 1192677541518462450242195190181174157138124123 (用户分别输入所列单词的频度) 预
188 14
【C++数据结构——树】哈夫曼树(头歌实践教学平台习题) 【合集】
|
存储 C语言
数据结构基础详解(C语言): 树与二叉树的应用_哈夫曼树与哈夫曼曼编码_并查集_二叉排序树_平衡二叉树
本文详细介绍了树与二叉树的应用,涵盖哈夫曼树与哈夫曼编码、并查集以及二叉排序树等内容。首先讲解了哈夫曼树的构造方法及其在数据压缩中的应用;接着介绍了并查集的基本概念、存储结构及优化方法;随后探讨了二叉排序树的定义、查找、插入和删除操作;最后阐述了平衡二叉树的概念及其在保证树平衡状态下的插入和删除操作。通过本文,读者可以全面了解树与二叉树在实际问题中的应用技巧和优化策略。
287 2
|
机器学习/深度学习 存储
数据结构学习记录——哈夫曼树(什么是哈夫曼树、哈夫曼树的定义、哈夫曼树的构造、哈夫曼树的特点、哈夫曼编码)
数据结构学习记录——哈夫曼树(什么是哈夫曼树、哈夫曼树的定义、哈夫曼树的构造、哈夫曼树的特点、哈夫曼编码)
440 1
|
存储 NoSQL 程序员
Redis -- 常用数据结构,认识数据类型和编码方式
Redis -- 常用数据结构,认识数据类型和编码方式
101 2
|
存储 NoSQL 算法
Redis源码、面试指南(2)内存编码数据结构(下)
Redis源码、面试指南(2)内存编码数据结构
119 4
|
存储 NoSQL API
Redis源码、面试指南(2)内存编码数据结构(上)
Redis源码、面试指南(2)内存编码数据结构
122 0
|
编译器
【数据结构】哈夫曼树编译码器【课程设计】
【数据结构】哈夫曼树编译码器【课程设计】
|
10月前
|
存储 算法
非递归实现后序遍历时,如何避免栈溢出?
后序遍历的递归实现和非递归实现各有优缺点,在实际应用中需要根据具体的问题需求、二叉树的特点以及性能和空间的限制等因素来选择合适的实现方式。
216 59
|
3月前
|
编译器 C语言 C++
栈区的非法访问导致的死循环(x64)
这段内容主要分析了一段C语言代码在VS2022中形成死循环的原因,涉及栈区内存布局和数组越界问题。代码中`arr[15]`越界访问,修改了变量`i`的值,导致`for`循环条件始终为真,形成死循环。原因是VS2022栈区从低地址到高地址分配内存,`arr`数组与`i`相邻,`arr[15]`恰好覆盖`i`的地址。而在VS2019中,栈区先分配高地址再分配低地址,因此相同代码表现不同。这说明编译器对栈区内存分配顺序的实现差异会导致程序行为不一致,需避免数组越界以确保代码健壮性。
46 0
栈区的非法访问导致的死循环(x64)