一、背景

编码是信息处理的基础(重新表示信息)。
普通的编码是等长编码,例如7位的ASCIL编码,对出现频率不同的字符都使用相同的编码长度。但其在传输和存储等情况下编码效率不高
可使用不等长编码,来压缩编码:高频字符编码长度更短,低频字符编码长度更长。
 
[例] 将百分制的考试成绩转换成五分制的成绩
按顺序分别编码。
按频率分别编码(高频短编码,类似于香农熵衡量随机变量的编码长度下界)。
这种贪心思想,可以找到一种平均最短编码长度-霍夫曼编码。可将构造平均最短编码转化为,构造平均查找长度最小的编码树(构造更有效的搜索树)

二、哈夫曼树

哈夫曼树的定义
带权路径长度就是所有叶子节点的编码长度乘以权重的和。 希望权重越高的叶子节点,编码长度越小。
[例] 有五个叶子结点,它们的权值为{1,2,3,4,5},用此权值序列可以构造出形状不同的多个二叉树。
哈夫曼树的构造
初始全是只有一个节点的树构成的森林 (优先队列存放树的根节点,每次合并后将新的树插入队列)
每次把权值最小的两棵二叉树合并 (自底向上)
 
使用最小堆,Huffman树为二叉树
typedef struct TreeNode *HuffmanTree;
struct TreeNode{
int Weight;
HuffmanTree Left, Right;
}; /* WPL WeightPathLength Cost越小编码越有效, O(NlogN) */
HuffmanTree Huffman( MinHeap H )
{
/* 假设H->Size个权值已经存在H->Elements[]->Weight里 */
int i;
HuffmanTree T;
BuildMinHeap(H); /* 将H->Elements[]按权值调整为最小堆 */
/* 做 H->Size - 1 次合并 */
for (i = 1; i < H->Size; i++)
{
T = malloc( sizeof( struct TreeNode) ); /* 建立新结点 */
T->Left = DeleteMin(H); /* 从最小堆中删除一个结点,作为新T的左子结点 */ T->Right = DeleteMin(H);
/* 从最小堆中删除一个结点,作为新T的右子结点 */
T->Weight = T->Left->Weight + T->Right->Weight; /*计算新权值*/ Insert( H, T ); /*将新T插入最小堆*/
}
T = DeleteMin(H); return T; int WPL( HuffmanTree H )
{
return H->Weight;
}

  

哈夫曼树的特点
  • 没有度为1的结点;
  • 哈夫曼树的任意非叶节点的左右子树交换后仍是哈夫曼树;
  • n个叶子结点的哈夫曼树共有2n-1个结点;
对同一组权值{w1 ,w2, …… , wn},是否存在不同构的两棵哈夫曼树呢?存在,当存在相同权值的根节点时。
对一组权值{ 1, 2 , 3, 3 }},不同构的两棵哈夫曼树:
哈夫曼编码
给定一段字符串,如何对字符进行编码,使得该字符串的编码存储空间最少?
[例] 假设有一段文本,包含58个字符,并由以下7个字符构:a,e,i, s,t,空格(sp),换行(nl);这7个字符出现的次数不同。如何对这7个字符进行编码,使得总编码空间最少?
[分析]
(1)用等长ASCII编码:58 ×8 = 464位;
(2)用等长3位编码:58 ×3 = 174位;
(3)不等长编码:出现频率高的字符用的编码短些,出现频率低的字符则可以编码长些?
 
怎么进行不等长编码?如何避免二义性?
  • 前缀码prefix code:任何字符的编码,都不是另一字符编码的前缀
可以无二义地解码(判定字符是否都在叶结点上,没有字符在路径上,不然解码时会有歧义)
 
用二叉树进行编码:1)左右分支:0、1; 2)字符只在叶结点上
[例] 四个字符的频率: a:4, u:1, x:2, z:1
〖例〗哈夫曼编码
 
题外话,这种使用优先队列的方法,在层次聚类里也有。

【数据结构】哈夫曼树与哈夫曼编码(Huffman Encoding)的更多相关文章

  1. 数据结构图文解析之:哈夫曼树与哈夫曼编码详解及C++模板实现

    0. 数据结构图文解析系列 数据结构系列文章 数据结构图文解析之:数组.单链表.双链表介绍及C++模板实现 数据结构图文解析之:栈的简介及C++模板实现 数据结构图文解析之:队列详解与C++模板实现 ...

  2. Java数据结构(十二)—— 霍夫曼树及霍夫曼编码

    霍夫曼树 基本介绍和创建 基本介绍 又称哈夫曼树,赫夫曼树 给定n个权值作为n个叶子节点,构造一棵二叉树,若该树的带权路径长度(wpl)达到最小,称为最优二叉树 霍夫曼树是带权路径长度最短的树,权值较 ...

  3. Java 树结构实际应用 二(哈夫曼树和哈夫曼编码)

     赫夫曼树 1 基本介绍 1) 给定 n 个权值作为 n 个叶子结点,构造一棵二叉树,若该树的带权路径长度(wpl)达到最小,称这样的二叉树为 最优二叉树,也称为哈夫曼树(Huffman Tree), ...

  4. C语言数据结构之哈夫曼树及哈夫曼编码的实现

    代码清单如下: #pragma once #include<stdio.h> #include"stdlib.h" #include <string.h> ...

  5. 10: java数据结构和算法: 构建哈夫曼树, 获取哈夫曼编码, 使用哈夫曼编码原理对文件压缩和解压

    最终结果哈夫曼树,如图所示: 直接上代码: public class HuffmanCode { public static void main(String[] args) { //获取哈夫曼树并显 ...

  6. 04-树6. Huffman Codes--优先队列(堆)在哈夫曼树与哈夫曼编码上的应用

    题目来源:http://www.patest.cn/contests/mooc-ds/04-%E6%A0%916 In 1953, David A. Huffman published his pap ...

  7. java实现哈弗曼树和哈夫曼树压缩

    本篇博文将介绍什么是哈夫曼树,并且如何在java语言中构建一棵哈夫曼树,怎么利用哈夫曼树实现对文件的压缩和解压.首先,先来了解下什么哈夫曼树. 一.哈夫曼树 哈夫曼树属于二叉树,即树的结点最多拥有2个 ...

  8. c++实现哈夫曼树,哈夫曼编码,哈夫曼解码(字符串去重,并统计频率)

    #include <iostream> #include <iomanip> #include <string> #include <cstdlib> ...

  9. Python 算法(2) 哈夫曼编码 Huffman Encoding

    这个问题原始是用来实现一个可变长度的编码问题,但可以总结成这样一个问题,假设我们有很多的叶子节点,每个节点都有一个权值w(可以是任何有意义的数值,比如它出现的概率),我们要用这些叶子节点构造一棵树,那 ...

  10. hdu 2527:Safe Or Unsafe(数据结构,哈夫曼树,求WPL)

    Safe Or Unsafe Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)To ...

随机推荐

  1. XXE注入详解

    XML介绍 XML全称可扩展标记语言(EXtensible Markup Language),XML跟HTML格式类似,但是作用不同,XML侧重于数据传输,HTML注重于标记语言,也就是说XML其实是 ...

  2. 【链表】链表OJ-力扣2074. 反转偶数长度组的节点【超详细的算法解释】

    说在前面 今天博主给大家带来的是力扣上的一道链表OJ,完成这道题后,博主感觉这题覆盖了很多链表的解题思想,另外,这道题对指针的控制也是比较高的.在这里博主将这道好题分享给大家! 另外,对于链表等数据结 ...

  3. SpringBoot 多模块开发 笔记(一)

    多模块开发 简易版 dao 层 也可以说是 Mapper 层 web 层 将 controller 放在这一层 还有 统一返回类型 和 自定义异常 也在放在这里 启动类也放在这里 model 层 也就 ...

  4. go中的 位预算,反码、补码、原码

    https://baike.baidu.com/item/%E4%BD%8D%E8%BF%90%E7%AE%97/6888804 首先关于"位运算",看下百度百科就行了. 总结:在 ...

  5. NOI 2023 题解

    Copper Loser 的题解-- Day1 T1 方格染色 有一个 \(n\times m\) 的网格,有 \(Q\) 次操作,每次形如有三种:将 \((x_i+j,y_i)\)/\((x_i,y ...

  6. NC200324 魔改森林

    题目链接 题目 题目描述 曾经有一道叫做迷雾森林的题目,然而牛牛认为地图中的障碍太多,实在是太难了,所以删去了很多点,出了这道题. 牛牛给出了一个n行m列的网格图 初始牛牛处在最左下角的格点上(n+1 ...

  7. comm命令

    comm命令 comm命令用于比较两个已排过序的文件,该命令会一列列地比较两个已排序文件的差异,并将其结果显示出来,如果没有指定任何参数,则会把结果分成3列显示:第1列仅是在第1个文件中出现过的列,第 ...

  8. Mysql错误消息 语言设置

    今天操作数据库的时候,mysql错误返回语句 ,一直报的是非英语的语言 ,百般纠结 ,简单的还大致能猜出意思 , 复杂了就会实在看不懂的 ,举个简单的如下: [Err] 1064 - Erreur d ...

  9. JS实现提示文本框可输入剩余字数

    最近在设计写博客功能时,涉及到留言框输入字数限制,需要给用户剩余数字提示. 参考文章:https://www.cnblogs.com/crazytrip/p/4968230.html 实现效果: 源码 ...

  10. 小红书 x Hugging Face 邀请你一起晒「创意新春照」

    不藏了,近期全网爆火的AI 写真项目 InstantID,正是来自小红书社区技术创作发布团队. 为了迎接龙年春节的到来,我们的InstantID全新推出「Spring Festival」新春风格!并与 ...