哈夫曼(Huffman)编码
哈夫曼编码(Huffman Coding)是一种非常经典的编码方式,属于可变字长编码(VLC)的一种,通过构造带权路径长度最小的最优二叉树以达到数据压缩的目的。
哈弗曼编码实现起来也非常简单,在实际的笔试面试过程中有可能会遇到,本文主要介绍具体的编码原理,以及使用STL的优先队列进行实现。
一 编码原理
哈夫曼编码是一种可变长的编码,它依据字符出现的概率来决定字符编码的长度,使得出现概率大的字符编码长度短,出现概率小的字符的编码长度长,于是可以减少整体的编码的长度。
哈弗曼编码时首先根据待编码的文本统计出每个字符出现的概率,组成初始的节点。然后每次取出概率最小的两个节点,新建一个节点,使得新建节点的左右儿子为选取的两个节点,并且其概率是两个节点概率之和,把新建的节点再放进所有节点中重新选择最小的两个节点。重复此过程直到只剩一个节点,这个就是哈夫曼树的根节点。
以下以字符串"aaaaaabbbbccddd"为例进行说明,为了方便,以字符出现的频数来代替频率(实际中通常使用的是频率,二者效果上是一样的),经过统计,可以知道每个字符出现的频数为
| a | b | c | d |
| 6 | 4 | 2 | 3 |
具体建树过程如下:
- 首先节点权值为6、4、2、3,选择最小的2和3,组成一个根节点为5的组合节点。
- 当前节点权值为6、4、5,选择最小的4和5,组成一个根节点为9的组合节点。
- 当前节点权值为6、9,选择最小的6和9,组成一个根节点为15的组合节点。
- 当前节点权值为15,只有一个节点,哈夫曼树建立完成。
图示如下:

要从哈夫曼树得到每个字符的编码,只要在哈夫曼树中从根节点遍历到该字符节点,每次向左走时加一个0,向右走时加一个1,最终得到的字符串即为该字符的编码字符串。
如从上图可以看到,a的编码为0,b的编码为10,c的编码为110,d的编码为111。
当遇到一个新的字符串时,比如说"abcd",要对其编码,只需要把其中的每个字符相应地替换成其编码字符串即可。
当已知一个编码后的字符串,比如说"010110111",要对其解码时,只需从左到右依次扫描该编码串,当读到的串在哈弗曼编码表里有对应的字符时即解码为该字符,然后继续扫描。
在这个例子中,读到第一个0时即可解码为a,读到10时可以解码为b,以此类推,最终得到解码后的结果为abcd。
哈夫曼编码之所以可以这样解码,是因为它是一种前缀编码,任何一个字符的编码都不会是另一个字符编码的前缀。于是给定一个编码后的串,其解码的结果是唯一的。
哈夫曼(Huffman)编码的更多相关文章
- 重温经典之赫夫曼(Huffman)编码
先看看赫夫曼树假设有n个权值{w1,w2,…,wn},构造一个有n个叶子结点的二叉树,每个叶子结点权值为wi,则其中带权路径长度WPL最小的二叉树称作赫夫曼树或最优二叉树. 赫夫曼树的构造,赫夫曼最早 ...
- 数据结构实训——哈夫曼(Huffman)编/译码器
题目4.哈夫曼(Huffman)编/译码器(限1人完成) [问题描述] 利用哈夫曼编码进行通信可以大大提高信道利用率,缩短信息传输时间,降低传输成本.但是,这要求在发送端通过一个编码系统对待传数据预先 ...
- [数据结构与算法]哈夫曼(Huffman)树与哈夫曼编码
声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...
- 哈夫曼(Huffman)树+哈夫曼编码
前天acm实验课,老师教了几种排序,抓的一套题上有一个哈夫曼树的题,正好之前离散数学也讲过哈夫曼树,这里我就结合课本,整理一篇关于哈夫曼树的博客. 主要摘自https://www.cnblogs.co ...
- C++哈夫曼树编码和译码的实现
一.背景介绍: 给定n个权值作为n个叶子结点,构造一棵二叉树,若带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman Tree).哈夫曼树是带权路径长度最短的树,权值较大的 ...
- puk1521 赫夫曼树编码
Description An entropy encoder is a data encoding method that achieves lossless data compression by ...
- 数据结构-哈夫曼(Huffman)
#include <iostream> #include <cstdio> #include <malloc.h> #define LIST_INIT_SIZE 1 ...
- 数据压缩之经典——哈夫曼编码(Huffman)
(笔记图片截图自课程Image and video processing: From Mars to Hollywood with a stop at the hospital的教学视频,使用时请注意 ...
- Huffman编码实现电文的转码与译码
//first thing:thanks to my teacher---chenrong Dalian Maritime university /* 构造Huffman Tree思路: ( ...
随机推荐
- HDU5790 Prefix 字典树+主席树
分析:这个题和spoj的d_query是一个题,那个是求一段区间里有多少个不同的数字,这里是统计有多少个不同的前缀 用字典树进行判重,(和查询不同的数字一样)对于每个不同的前缀,只保留它最后一次出现的 ...
- codeforces 675E Trains and Statistic 线段树+贪心统计
分析:这个题刚看起来无从下手 但是我们可以先简化问题,首先可以固定起点i,求出i+1到n的最小距离 它可以到达的范围是[i+1,a[i]],贪心的想,我们希望换一次车可以到达的距离尽量远 即:找一个k ...
- 精雕细琢 35 套精美的 PSD 图标素材
设计师总是有独特的创意和精雕细琢的精湛技术,让我们值得去欣赏和借鉴,如梦想天空所表达的:非常感谢那些很有才华的设计师分享它们的劳动成果,让更多的人可以使用他们的创意设计.今天,本文与大家分享35套精美 ...
- kobo boot scripts
#!/bin/sh pkill nickel eink_enable_autoupdate rm -rf /debian/tmp/* /debian/tmp/.* 2>/dev/null mou ...
- UNIX系统文件
密码文件 密码文件又称用户数据库,一般为/etc/passwd,对应的结构为struct passwd,该文件内容大体如下: 描述 passwd字段 用户名 char* pw_name 加密密码 ch ...
- 微软Azure开始支持Docker技术
前一段时间还在与微软的技术人员讨论媒体转换服务的效率问题,如果应用 Docker将会有质的提高,没想到国外的Azure已经开始支持了,相信国内Azure支持也不远了.微软正在努力确保Azure成为开发 ...
- JAVA与数据库开发(JDBC-ODBC、SQL Server、MySQL)
1)配置数据库环境和驱动 2)设计数据库结构并创建数据库 3)对数据库进行增删改查操作...
- 基础排序算法,java实现(快速,冒泡,选择,堆排序,插入)
1.冒泡排序: (1)比较相邻的元素.如果第一个比第二个大,就交换他们两个. (2)外面再套个循环就行. 算法复杂度:O(N2) 不罗嗦,上代码: //冒泡排序(两两交换,外加一个外循环) pub ...
- JavaFx2.0中CSS的应用
http://user.qzone.qq.com/773534839#!app=2&via=QZ.HashRefresh&pos=1326994508 ———————————————— ...
- 常用的Activex 控件
1. Flash Player ActiveX Control 6.0.47.0 与FLASH 6.0配套的浏览器端动画播放插件 download.pchome.n ...