哈夫曼编码方法Huffman
哈夫曼编码(HuffmanCoding)-贪心策略
哈夫曼编码(HuffmanCoding)-贪⼼策略 哈夫曼编码是⼀种编码⽅式,是可变字长编码(VLC)的⼀种。
其中变长编码表是通过⼀种评估来源符号出现机率的⽅法得到的,出现机率⾼的字母使⽤较短的编码,反之出现机率低的则使⽤较长的编码,这便使编码之后的字符串的平均长度、期望值降低,从⽽达到⽆损压缩数据的⽬的。
⾯试题常常会考的⼀种思想,笔试题就更不⽤说了,选择题直接让你构造哈夫曼树。
哈夫曼编码的图形构造是⼀棵树,每个节点具有权值,权值越⼤的节点越靠近树根,越⼩的节点就越远离树根,从它的定义来看,想到的就是贪⼼策略。
⾸先如何构造哈夫曼编码树:每次从树集合中找出权值最⼩的两棵树分别作为左、右⼦树,然后合并它们作为他们的⽗节点,其权值为两颗⼦树的权值和。
步骤: 1 :确定合适的数据结构(要知道他的左右⼦树,双亲,权值) 2:初始化,构造n颗节点为n的字符单节点树集合T={t1,t2,t3,t4···········tn},保证按权值排序,并且每棵树只有树根 3:如果集合中只剩下⼀棵树,那么哈夫曼树就构造成功,直接跳转到步骤6,否则就是从集合中继续拿出权值最⼩的⼦树x作为左⼦树,第⼆⼩的y作为右⼦树,并将它们合并到⼀颗z树中, z的权值为左右⼦树权值之和 4:从T集合中删除x,y 把新树z加⼊到集合T中 5:重复步骤3~4 6:约定左分⽀上的编码都是0,右分⽀上的编码都是1,从叶⼦节点开始逆序求出树的编码 对于编码字符出现的频率:1)将信源符号的概率按减⼩的顺序排队。
2)把两个最⼩的概率相加,并继续这⼀步骤,始终将较⾼的概率分⽀放在右边,直到最后变成概率1。
3)画出由概率1处到每个信源符号的路径,顺序记下沿路径的0和1,所得就是该符号的霍夫曼码字。
4)将每对组合的左边⼀个指定为0,右边⼀个指定为1(或相反)。
贪心算法实现Huffman编码
算法分析与设计实验报告第次实验附录:完整代码#include <iostream>#include <string>#include<stdio.h>#include <time.h>#include <iomanip>#include <vector>#include<algorithm>using namespace std;class Huffman{public:char elementChar;//节点元素int weight;//权重char s;//哈夫曼编码Huffman* parent;//父节点Huffman* leftChild;//左孩子Huffman* rightChild;//右孩子public:Huffman();Huffman(char a, int weight);bool operator < (const Huffman &m)const { return weight < m.weight;} };Huffman::Huffman(){this->s = ' ';this->elementChar = '*';//非叶子节点this->parent = this->leftChild = this->rightChild = NULL;}Huffman::Huffman(char a, int weight):elementChar(a),weight(weight) {this->s = ' ';this->elementChar = '*';//非叶子节点this->parent = this->leftChild = this->rightChild = NULL;}//递归输出哈夫曼值void huffmanCode(Huffman & h){if(h.leftChild == NULL && h.rightChild == NULL){//如果是叶子节点,输出器哈夫曼编码string s;Huffman temp = h;while(temp.parent != NULL){s = temp.s + s;temp = *temp.parent;}cout << h.elementChar << "的哈夫曼编码是:" << s << endl; return;}//左孩子huffmanCode(*h.leftChild);//右孩子huffmanCode(*h.rightChild);}int main(){int l,p=0;double q=0.0;clock_t start,end,over;start=clock();end=clock();over=end-start;start=clock();string huffmanStr;cout << "请输入一串字符序列:" << endl;cin >> huffmanStr;//得到字符串信息int i=0,j,n,m[100],h,k=0;char cha[100];n = huffmanStr.length();cout << "字符串总共有字符" << n << "个" << endl;for(int i = 0; i < n; i++){j = 0; h = 0;while(huffmanStr[i] != huffmanStr[j])j++;if(j == i){cha[k] = huffmanStr[i];cout << "字符" << cha[k] << "出现";}//如果j !=i 则略过此次循环elsecontinue;for(j = i; j < n; j++){if(huffmanStr[i] == huffmanStr[j])h++;}cout << h << "次" << endl;m[k] = h;k++;}//哈夫曼编码Huffman huffmanTemp;vector < Huffman > huffmanQueue;//初始化队列for(int i = 0; i < k; i++){huffmanTemp.elementChar = cha[i];huffmanTemp.weight = m[i];huffmanQueue.push_back(huffmanTemp);}//得到哈夫曼树所有节点int huffmanQueue_index = 0;sort(huffmanQueue.begin(), huffmanQueue.end());while(huffmanQueue.size() < 2 * k - 1){//合成最小两个节点的父节点huffmanTemp.weight = huffmanQueue[huffmanQueue_index].weight + huffmanQueue[huffmanQueue_index + 1].weight;huffmanQueue[huffmanQueue_index].s = '0';huffmanQueue[huffmanQueue_index + 1].s = '1';huffmanTemp.elementChar = '*';//将父节点加入队列huffmanQueue.push_back(huffmanTemp);sort(huffmanQueue.begin(), huffmanQueue.end());huffmanQueue_index += 2;}//把所有节点构造成哈夫曼树int step = 0;//步长while(step + 2 < 2 * k){for(int j = step + 1; j <= huffmanQueue.size(); j++){if(huffmanQueue[j].elementChar == '*' && huffmanQueue[j].leftChild == NULL && (huffmanQueue[j].weight == huffmanQueue[step].weight + huffmanQueue[step+1].weight)){huffmanQueue[j].leftChild = &huffmanQueue[step];huffmanQueue[j].rightChild = &huffmanQueue[step+1];huffmanQueue[step].parent = huffmanQueue[step+1].parent = &huffmanQueue[j]; break;}}step += 2;}//序列最后一个元素,即哈弗曼树最顶端的节点huffmanTemp = huffmanQueue.back();huffmanCode(huffmanTemp);for(l=0;l<1000000000;l++)p=p+l;end=clock();printf("The time is %6.3f",(double)(end-start-over)/CLK_TCK);return 0;}。
哈夫曼编码
单个字母编码时编码效率不高
信源字母集大时不易实现(香农-费诺码可解决)
硬件实现时需要缓冲寄存器(变长码固有的缺陷) 差错扩散(可增加信道校验码) 必须知道信源的统计特性(通用信源编码不需要)
School of Information and Mathematics
谢谢各位老师!
结论
结论:在哈夫曼编码过程中,对缩减信源符号按概率 由大到小的顺序重新排列时,应使合并后的新符号尽 可能排在靠前的位置,这样可使合并后的新符号重复
编码次数减少,使短码得到充分利用。
School of Information and Mathematics
结论
定理:在变长编码中,若各码字长度严格按照所对应符号
引例—色子游戏
点数出现 的频率
School of Information and Mathematics
引例—色子游戏
按概率编码
School of Information and Mathematics
引例—莫尔斯电报码
莫尔斯电报码:按照英文字母出现的概率编码,
在英文中,e的出现概率很高,而z的出现概率则最低。
例题
可见:第二种编码方法的码长方差要小许多。意味着第 二种编码方法的码长变化较小,比较接近于平均码长。
第一种方法编出的5个码字有4种不同的码长;
第二种方法编出的码长只有两种不同的码长;
显然,第二种编码方法更简单、更容易实现,所以
更好。
School of Information and Mathematics
哈夫曼编码
哈夫曼编码算法: (1) 信源符号按概率分布大小,以递减次序排列; (2) 取两个最小的概率,分别赋以“0”,“1”; 然后把这两个概率值相加,作为新概率值与其他概率重新排序 (3) 按重排概率值,重复(2)…,
哈夫曼编码encode
哈夫曼编码(Huffman Coding)From May10 AlgorithmJump to: navigation, searchTemplate:Translation哈夫曼编码(Huffman Coding)是一種編碼方式,以哈夫曼树─即最优二叉树,带权路径长度最小的二叉树,经常应用于数据压缩。
在计算机信息处理中,“哈夫曼编码”是一种一致性编码法(又称"熵编码法"),用于数据的无损耗压缩。
这一术语是指使用一张特殊的编码表将源字符(例如某文件中的一个符号)进行编码。
这张编码表的特殊之处在于,它是根据每一个源字符出现的估算概率而建立起来的(出现概率高的字符使用较短的编码,反之出现概率低的则使用较长的编码,这便使编码之后的字符串的平均期望长度降低,从而达到无损压缩数据的目的)。
这种方法是由David.A.Huffman发展起来的。
例如,在英文中,e的出现概率很高,而z的出现概率则最低。
当利用哈夫曼编码对一篇英文进行压缩时,e极有可能用一个位(bit)来表示,而z则可能花去25个位(不是26)。
用普通的表示方法时,每个英文字母均占用一个字节(byte),即8个位。
二者相比,e使用了一般编码的1/8的长度,z则使用了3倍多。
倘若我们能实现对于英文中各个字母出现概率的较准确的估算,就可以大幅度提高无损压缩的比例。
In computer science, Huffman coding is an entropy encoding algorithm used for lossless data compression. The term refers to the use of a variable-length code table for encoding a source symbol (such as a character in a file) where the variable-length code table has been derived in a particular way based on the estimated probability of occurrence for each possible value of the source symbol. It was developed by David A. Huffman as a Ph.D. student at MIT in 1952, and published in A Method for the Construction of Minimum-Redundancy Codes.哈夫曼树又称最优二叉树,是一种带权路径长度最短的二叉树。
哈夫曼编码算法实现
哈夫曼编码(Huffman Coding)是一种常见的数据压缩算法,它通过构建哈夫曼树(Huffman Tree)来实现。
以下是一个简单的哈夫曼编码算法的实现示例,使用Python 语言:pythonCopy codeimport heapqfrom collections import defaultdictclass HuffmanNode:def __init__(self, char, frequency):self.char = charself.frequency = frequencyself.left = Noneself.right = Nonedef __lt__(self, other):return self.frequency < other.frequencydef build_huffman_tree(data):frequency = defaultdict(int)for char in data:frequency[char] += 1priority_queue = [HuffmanNode(char, freq) for char, freq in frequency.items()]heapq.heapify(priority_queue)while len(priority_queue) > 1:node1 = heapq.heappop(priority_queue)node2 = heapq.heappop(priority_queue)merged_node = HuffmanNode(None, node1.frequency + node2.frequency)merged_node.left = node1merged_node.right = node2heapq.heappush(priority_queue, merged_node)return priority_queue[0]def build_huffman_codes(root, current_code="", codes={}):if root:if root.char is not None:codes[root.char] = current_codebuild_huffman_codes(root.left, current_code + "0", codes)build_huffman_codes(root.right, current_code + "1", codes)return codesdef huffman_encoding(data):if not data:return None, Noneroot = build_huffman_tree(data)codes = build_huffman_codes(root)encoded_data = "".join([codes[char] for char in data])return encoded_data, rootdef huffman_decoding(encoded_data, root):if not encoded_data or not root:return Nonecurrent_node = rootdecoded_data = ""for bit in encoded_data:if bit == "0":current_node = current_node.leftelse:current_node = current_node.rightif current_node.char is not None:decoded_data += current_node.charcurrent_node = rootreturn decoded_data# 示例data = "abracadabra"encoded_data, tree_root = huffman_encoding(data) decoded_data = huffman_decoding(encoded_data, tree_root)print("Original data:", data)print("Encoded data:", encoded_data)print("Decoded data:", decoded_data)。
哈夫曼编码原理及方法
哈夫曼编码原理及方法哈夫曼编码(Huffman Coding)是一种变长编码(Variable Length Code)的压缩算法。
它的原理是将频率较高的字符用较短的编码,频率较低的字符用较长的编码,以此降低数据的传输成本。
下面将详细介绍哈夫曼编码的原理及方法。
一、哈夫曼编码的原理哈夫曼编码的原理基于贪心算法(Greedy Algorithm),即对每个要编码的字符进行评估,按照字符在文本中出现的频率多少,将频率高的字符赋予较短的编码,频率低的字符赋予较长的编码。
这样在实际使用中,字符出现频率越高的编码长度越短,从而达到压缩数据的目的。
二、哈夫曼编码的方法1. 构建哈夫曼树(Huffman Tree)构建哈夫曼树的过程首先要确定每个字符在文本中出现的频率,然后将每个字符看作一个节点,并按照其频率大小建立一个小根堆(Min Heap)。
接下来,选取频率最小的两个节点,将它们合并到一起作为一个新的节点,并更新频率值,然后继续重复以上步骤,直到堆中只剩下一个节点,即为哈夫曼树的根节点。
2. 生成哈夫曼编码生成哈夫曼编码可以采用递归的方式,从根节点开始向左遍历时,将标记为 0,向右遍历时,将标记为 1,直到叶节点为止,然后向上回溯,将遍历的结果保存下来,得到该叶节点的哈夫曼编码。
遍历完所有的叶子节点后,即可得到所有字符的哈夫曼编码。
3. 压缩数据在使用哈夫曼编码进行数据压缩时,将字符替换为其对应的哈夫曼编码,这样可以将原始数据压缩为更小的数据量,达到压缩数据的目的。
在解压数据时,需要根据已生成的哈夫曼树,将压缩后的数据转换为原始数据,即将哈夫曼编码转换为对应的字符。
三、哈夫曼编码的优缺点哈夫曼编码的优点是具有压缩比高、压缩速度快、压缩后的数据无损还原等特点,可以广泛用于图像、音频、视频等多种数据类型的压缩。
同时,由于哈夫曼编码采用变长编码方式,所以可以使用相对较短的编码表示经常出现的字符,从而达到更好的压缩效果。
哈夫曼(huffman)树和哈夫曼编码
哈夫曼(huffman)树和哈夫曼编码讨论QQ群:待定哈夫曼树哈夫曼树也叫最优二叉树(哈夫曼树)问题:什么是哈夫曼树?例:将学生的百分制成绩转换为五分制成绩:≥90 分: A,80~89分: B,70~79分: C,60~69分: D,<60分: E。
if (a < 60){b = 'E';}else if (a < 70) {b = ‘D’;}else if (a<80) {b = ‘C’;}else if (a<90){b = ‘B’;}else {b = ‘A’;}判别树:用于描述分类过程的二叉树。
如果每次输入量都很大,那么应该考虑程序运行的时间如果学生的总成绩数据有10000条,则5%的数据需1 次比较,15%的数据需 2 次比较,40%的数据需 3 次比较,40%的数据需 4 次比较,因此 10000 个数据比较的次数为: 10000 (5%+2×15%+3×40%+4×40%)=31500次此种形状的二叉树,需要的比较次数是:10000 (3×20%+2×80%)=22000次,显然:两种判别树的效率是不一样的。
问题:能不能找到一种效率最高的判别树呢?那就是哈夫曼树回忆树的基本概念和术语路径:若树中存在一个结点序列k1,k2,…,kj,使得ki是ki+1的双亲,则称该结点序列是从k1到kj的一条路径。
路径长度:等于路径上的结点数减1。
结点的权:在许多应用中,常常将树中的结点赋予一个有意义的数,称为该结点的权。
结点的带权路径长度:是指该结点到树根之间的路径长度与该结点上权的乘积。
树的带权路径长度:树中所有叶子结点的带权路径长度之和,通常记作:其中,n表示叶子结点的数目,wi和li分别表示叶子结点ki的权值和树根结点到叶子结点ki之间的路径长度。
赫夫曼树(哈夫曼树,huffman树)定义:在权为w1,w2,…,wn的n个叶子结点的所有二叉树中,带权路径长度WPL最小的二叉树称为赫夫曼树或最优二叉树。
哈夫曼编码1952年Huffma...
第三章多媒体数据压缩3.1 数据压缩的基本原理和方法3.1 数据压缩的基本原理和方法•压缩的必要性音频、视频的数据量很大,如果不进行处理,计算机系统几乎无法对它进行存取和交换。
例如,一幅具有中等分辨率(640×480)的真彩色图像(24b/像素),它的数据量约为7.37Mb/帧,一个100MB(Byte)的硬盘只能存放约100帧图像。
若要达到每秒25帧的全动态显示要求,每秒所需的数据量为184Mb,而且要求系统的数据传输率必须达到184Mb/s。
对于声音也是如此,若采用16b样值的PCM编码,采样速率选为44.1kHZ ,则双声道立体声声音每秒将有176KB的数据量。
3.1 数据压缩的基本原理和方法•视频、图像、声音有很大的压缩潜力信息论认为:若信源编码的熵大于信源的实际熵,该信源中一定存在冗余度。
原始信源的数据存在着很多冗余度:空间冗余、时间冗余、视觉冗余、听觉冗余等。
3.1.1 数据冗余的类型•空间冗余:在同一幅图像中,规则物体和规则背景的表面物理特性具有相关性,这些相关性的光成像结果在数字化图像中就表现为数据冗余。
–一幅图象中同一种颜色不止一个象素点,若相邻的象素点的值相同,象素点间(水平、垂直)有冗余。
–当图象的一部分包含占主要地位的垂直的源对象时,相邻线间存在冗余。
3.1.1 数据冗余的类型•时间冗余:时间冗余反映在图像序列中就是相邻帧图像之间有较大的相关性,一帧图像中的某物体或场景可以由其它帧图像中的物体或场景重构出来。
–音频的前后样值之间也同样有时间冗余。
–若图象稳定或只有轻微的改变,运动序列帧间存在冗余。
3.1.1 数据冗余的类型•信息熵冗余:信源编码时,当分配给第i 个码元类的比特数b (y i )=-log p i ,才能使编码后单位数据量等于其信源熵,即达到其压缩极限。
但实际中各码元类的先验概率很难预知,比特分配不能达到最佳。
实际单位数据量d>H (S ),即存在信息冗余熵。
哈夫曼编码算法详解
哈夫曼编码算法详解在计算机科学中,哈夫曼编码是一种压缩算法,也叫做霍夫曼编码,是由霍夫曼(Huffman)在1952年首创的。
霍夫曼编码是一种无损压缩算法,可以对文本文件、音频文件、图像文件等各种类型的文件进行压缩。
1. 哈夫曼编码的原理哈夫曼编码是基于频率统计的思想,通过统计每个字符在文件中出现的频率,选择出现频率最高的字符,将其映射为一组比特位,出现频率较低的字符则映射为比高的比特位,从而实现对文件的压缩。
通过哈夫曼编码,可以将文件压缩到原始大小的一半甚至更小。
2. 哈夫曼编码的实现哈夫曼编码的实现需要进行几个步骤:2.1 统计字符的出现频率从文件中读取字符,统计每个字符在文件中出现的次数,可以使用一个数组或字典来保存每个字符的出现次数。
对于英文文本来说,出现频率最高的字符是空格,其次是字母“e”。
2.2 构建哈夫曼树将所有的字符按照出现频率从小到大排序,选出出现频率最小的两个字符作为左右子节点,其父节点的出现频率为左右子节点出现频率之和。
重复这个过程,直到节点数为1,这样就得到了一棵哈夫曼树。
2.3 生成哈夫曼编码从哈夫曼树的根节点开始,遍历所有的节点,将左子节点标记为0,将右子节点标记为1,将所有的叶子节点的字符和对应的哈夫曼编码保存到一个字典中。
最终得到了每个字符对应的哈夫曼编码。
2.4 进行压缩将文件中每个字符替换为对应的哈夫曼编码,然后将所有的哈夫曼编码拼接成一个二进制数,在最后不足8位的位置补零,将其存储到文件中。
这样就完成了文件的压缩。
3. 哈夫曼编码的优点哈夫曼编码具有以下优点:3.1 压缩率高由于哈夫曼编码是根据不同字符的出现频率来进行编码的,出现频率高的字符用较短的编码表示,出现频率低的字符用较长的编码表示,能够最大限度地减少文件的大小,从而达到高的压缩率。
3.2 唯一解哈夫曼编码是通过构建哈夫曼树来得到每个字符对应的编码,哈夫曼树的构建是唯一的,因此哈夫曼编码也是唯一的。
哈夫曼二进制编码过程
哈夫曼二进制编码过程哈夫曼编码是一种二进制编码方式,广泛应用于数据压缩和通信领域。
它的构建过程具有一定的规律,通过这种编码方式,可以实现信息的高效传输和存储。
一、哈夫曼编码的简介哈夫曼编码(Huffman Coding)是一种可变长度编码方式,由美国计算机科学家David A.Huffman于1952年提出。
它是基于信息论原理,通过对字符出现的概率进行统计,构建出一种能够实现最高效率的编码方式。
二、哈夫曼编码的构建过程1.统计数据:首先对需要编码的字符出现的频率进行统计,将出现频率最高的字符赋予最小的编码长度,依次类推。
2.构建哈夫曼树:根据统计得到的字符频率,构建一棵哈夫曼树。
在树中,每个字符对应一个叶子节点,每个内部节点表示两个子节点的合并。
3.生成编码表:从哈夫曼树中得到每个字符对应的编码,形成编码表。
4.编码与解码:发送方根据编码表对字符进行编码,接收方根据编码表进行解码。
三、哈夫曼编码的实用性哈夫曼编码具有以下实用性:1.高效性:相较于固定长度编码,哈夫曼编码能够根据字符出现的概率自适应地分配编码长度,从而提高编码效率。
2.可靠性:哈夫曼编码具有唯一性,即相同的字符始终对应相同的编码,便于接收方解码。
3.通用性:哈夫曼编码可应用于各种数据压缩和通信场景,如文本、图像、音频等。
四、哈夫曼编码在现代通信中的应用现代通信技术中,哈夫曼编码得到了广泛应用,如:1.数据压缩:如zip、rar等压缩软件,采用哈夫曼编码对数据进行压缩,减少存储空间和传输时间。
2.通信协议:许多通信协议,如HTTP、FTP等,采用哈夫曼编码对传输数据进行编码,提高传输效率。
3.二维码:哈夫曼编码在二维码编码中也有应用,如QR码等。
五、哈夫曼编码的优点与局限性优点:1.高效:根据字符出现概率自适应分配编码长度,提高编码效率。
2.可靠性:唯一性编码,便于接收方解码。
3.通用:适用于多种数据类型和通信场景。
局限性:1.编码复杂度:构建哈夫曼树和生成编码表的过程较为复杂。
哈夫曼编码方法
哈夫曼编码方法
哈夫曼编码(Huffman coding)是一种常用的无损数据压缩算法,用于将源数据转换为可变长度的二进制编码。
它基于源数据中不同符号出现的概率来构建一棵哈夫曼树,然后使用该树来生成每个符号对应的编码。
下面是哈夫曼编码的基本步骤:
1. 统计符号频率:对源数据进行扫描,统计每个符号出现的频率或概率。
2. 构建哈夫曼树:根据符号的频率构建一棵哈夫曼树。
频率较高的符号在树中位置较浅,频率较低的符号在树中位置较深。
3. 生成编码:从根节点开始,沿着哈夫曼树的路径向下,给左子树赋值"0",给右子树赋值"1",直到达到叶子节点。
每个叶子节点的编码就是其路径上经过的0和1序列。
4. 压缩数据:使用生成的编码来代替源数据中的符号,将原始数据进行压缩。
哈夫曼编码的优势在于,频率较高的符号被赋予较短的编码,而频率较低的符号被赋予较长的编码,从而实现了数据压缩。
在解压缩时,使用相同的哈夫曼树,根据编码逐位进行解码,恢复原始数据。
哈夫曼编码在通信、数据存储和多媒体处理等领域广泛应用,能够有效地压缩数据并节省存储空间或传输带宽。
1/ 1。
huffman编码的原理
huffman编码的原理
Huffman编码是一种基于哈夫曼树的数据压缩算法,它利用字符出现的频率来构建一种高效的编码方案,使得出现频率较高的字符用较短的编码表示,而出现频率较低的字符用较长的编码表示。
Huffman编码的原理如下:
1. 统计字符出现的频率:遍历需要编码的数据,统计每个字符出现的频率。
2. 构建哈夫曼树:根据字符的频率,构建一颗哈夫曼树。
频率越高的字符在树中的位置越靠近根节点。
3. 分配编码:从根节点开始,向左走为0,向右走为1,分配每个字符的编码。
在树中,到达一个字符节点时,路径上的0和1的组合就是该字符的编码。
4. 生成编码表:将每个字符和对应的编码存储在一个编码表中,以便解压时查找。
5. 进行编码:根据生成的编码表,将需要编码的数据转换成对应的编码。
Huffman编码的特点是每个字符的编码都是唯一的,没有前缀码。
这意味着在解码时,只需要按照编码表,从根节点开始进行匹配,逐个字符解码,直到找到对应的字符为止。
由于Huffman编码利用了字符出现的频率,将频率高的字符使用较短的编码,这样可以大幅度减少编码后的数据量,从而实现了数据的压缩效果。
哈夫曼编码
• 哈夫曼(Huffman)编码是一种常用的压缩编码方法, 是Huffman于1952年为压缩文本文件建立的。
• 基本思想 – 通过减少编码冗余来达到压缩的目的。 – 统计符号的出现概率,建立一个概率统计表 • 将最常出现(概率大的)的符号用最短的编码, • 最少出现的符号用最长的编码。
01 20 0 1
40 0 1 0 1 30
0
10
(7)分配码字。将形成的二叉树的左节点标0,右节点 标1。把从最上面的根节点到最下面的叶子节点途中遇到的 0,1序列串起来,就得到了各级灰度的编码.
30 10 20 40 20 40 0 20 20 20 30 30 20 40 40 20
01 20 0 1
霍夫曼编码举例
30 10 20 40 20 40 0 20 20 20 30 30 20 40 40 20
(1) 统计出每级灰度出现的频率: 灰度值: 0 10 20 30 40 出现频率: 1/16 1/16 7/16 3/16 4/16
30 10 20 40 20 40 0 20 20 20 30 30 20 40 40 20
2/16 3/16 5/16 7/16
5/16 30 10 20 40
20 40 0 20
2/16
20 20 30 30
3/16
20 40 40 20
1/16
1/16
(4) 选出频率最小的两个值(2/16,3/16)作为二叉 树的两个叶子节点,将频率和5/16作为它们的根节点,新的 根节点再参与其它频率排序:
(2)从左到右把上述频率按从小到大的顺序排列。 灰度值: 0 10 30 40 20 出现频率: 1/16 1/16 3/16 4/16 7/16
哈夫曼编码简介(doc)
哈夫曼编码简介(doc)哈夫曼编码(Huffman Coding),又称霍夫曼编码,是一种编码方式,哈夫曼编码是可变字长编码(VLC)的一种。
Huffman于1952年提出一种编码方法,该方法完全依据字符出现概率来构造异字头的平均长度最短的码字,有时称之为最佳编码,一般就叫做Huffman编码(有时也称为霍夫曼编码)。
哈夫曼编码的原理哈夫曼编码的基本思路:输入一个待编码的串,首先统计串中各字符出现的次数,称之为频次,假设统计频次的数组为count,则哈夫曼编码每次找出count数组中的值最小的两个分别作为左右孩子,建立父节点,循环这个操作2*n-1-n次,这样就把霍夫曼树建好了,建树的过程需要注意,首先把count数组里面的n个值初始化为霍夫曼树的n个叶子节点,他们的孩子节点标号初始化为-1,父节点初始化为他本身的标号。
接下来是编码,每次从霍夫曼树的叶子节点出发,依次向上找,假设当前的节点标号是i,那么他的父节点必然是myhuffmantree.parent,如果i是myhuffmantree.parent的左节点,则该节点的路径为0,如果是右节点,则该节点的路径为1。
当向上找到一个节点,他的父节点标号就是他本身,就停止。
哈夫曼编码的具体步骤1、准备待编码的字符串;2、统计字符串中每个字符出现的次数;3、根据上面的数组,生成节点;4、构建霍夫曼树,每次删除链表中的两个节点,生成一个新节点,并将这个节点重新插入到链表合适位置;5、通过前序遍历,求出每个字符的二进制编码,同样设置一个长度为256的数组,下标为字符对应的ASCII码,没出现的字符编码为null,不考虑;6、根据求出的二进制编码替换原来的每个字符,得到整个字符串对应的二进制编码;7、将二进制编码按照没8位生成一个新字符,最后剩的不足8位的在后面补上count个0,计算一个新字符,补0的个数解码时需要使用;8、将生成的新字符替换二进制编码字符串,即可得到编码后的内容,长度将在一定程度变短;哈夫曼编码的特点1、哈夫曼编码方式保证了概率大的符号对应短码,概率小的符号对应长码,充分利用了短码;2、哈夫曼是一种即时码:由于代表信源符号的节点都是终端节点,因此其编码不可能是其他终端节点对应的编码的前缀,即哈夫曼编码所得的码字为即时码;3、哈夫曼编码是一种分组码,各个信源符号都被映射成一组固定次序的码符号;4、哈夫曼编码是一种唯一可解的码,任何符号序列只能以一种方式译码。
数据结构——哈夫曼(Huffman)树+哈夫曼编码
数据结构——哈夫曼(Huffman)树+哈夫曼编码前天acm实验课,⽼师教了⼏种排序,抓的⼀套题上有⼀个哈夫曼树的题,正好之前离散数学也讲过哈夫曼树,这⾥我就结合课本,整理⼀篇关于哈夫曼树的博客。
哈夫曼树的介绍Huffman Tree,中⽂名是哈夫曼树或霍夫曼树,它是最优⼆叉树。
定义:给定n个权值作为n个叶⼦结点,构造⼀棵⼆叉树,若树的带权路径长度达到最⼩,则这棵树被称为哈夫曼树。
这个定义⾥⾯涉及到了⼏个陌⽣的概念,下⾯就是⼀颗哈夫曼树,我们来看图解答。
(01) 路径和路径长度定义:在⼀棵树中,从⼀个结点往下可以达到的孩⼦或孙⼦结点之间的通路,称为路径。
通路中分⽀的数⽬称为路径长度。
若规定根结点的层数为1,则从根结点到第L层结点的路径长度为L-1。
例⼦:100和80的路径长度是1,50和30的路径长度是2,20和10的路径长度是3。
(02) 结点的权及带权路径长度定义:若将树中结点赋给⼀个有着某种含义的数值,则这个数值称为该结点的权。
结点的带权路径长度为:从根结点到该结点之间的路径长度与该结点的权的乘积。
例⼦:节点20的路径长度是3,它的带权路径长度= 路径长度 * 权 = 3 * 20 = 60。
(03) 树的带权路径长度定义:树的带权路径长度规定为所有叶⼦结点的带权路径长度之和,记为WPL。
例⼦:⽰例中,树的WPL= 1*100 + 2*50 +3*20 + 3*10 = 100 + 100 + 60 + 30 = 290。
⽐较下⾯两棵树上⾯的两棵树都是以{10, 20, 50, 100}为叶⼦节点的树。
左边的树WPL=2*10 + 2*20 + 2*50 + 2*100 = 360 右边的树WPL=350左边的树WPL > 右边的树的WPL。
你也可以计算除上⾯两种⽰例之外的情况,但实际上右边的树就是{10,20,50,100}对应的哈夫曼树。
⾄此,应该堆哈夫曼树的概念有了⼀定的了解了,下⾯看看如何去构造⼀棵哈夫曼树。
哈夫曼编码(Huffman Coding)
哈夫曼编码哈夫曼编码(Huffman Coding)是一种编码方式,哈夫曼编码是可变字长编码(VL C)的一种。
Huffman于1952年提出一种编码方法,该方法完全依据字符出现概率来构造异字头的平均长度最短的码字,有时称之为最佳编码,一般就叫作Huffman 编码。
以哈夫曼树─即最优二叉树,带权路径长度最小的二叉树,经常应用于数据压缩。
在计算机信息处理中,“哈夫曼编码”是一种一致性编码法(又称"熵编码法"),用于数据的无损耗压缩。
这一术语是指使用一张特殊的编码表将源字符(例如某文件中的一个符号)进行编码。
这张编码表的特殊之处在于,它是根据每一个源字符出现的估算概率而建立起来的(出现概率高的字符使用较短的编码,反之出现概率低的则使用较长的编码,这便使编码之后的字符串的平均期望长度降低,从而达到无损压缩数据的目的)。
这种方法是由David.A.Huffman发展起来的。
例如,在英文中,e的出现概率很高,而z的出现概率则最低。
当利用哈夫曼编码对一篇英文进行压缩时,e极有可能用一个位(bit)来表示,而z则可能花去25个位(不是26)。
用普通的表示方法时,每个英文字母均占用一个字节(byte),即8个位。
二者相比,e使用了一般编码的1/8的长度,z则使用了3倍多。
倘若我们能实现对于英文中各个字母出现概率的较准确的估算,就可以大幅度提高无损压缩的比例。
本文描述在网上能够找到的最简单,最快速的哈夫曼编码。
本方法不使用任何扩展动态库,比如STL或者组件。
只使用简单的C函数,比如:memset,memmove,qsort,malloc,realloc和memcpy。
因此,大家都会发现,理解甚至修改这个编码都是很容易的。
背景哈夫曼压缩是个无损的压缩算法,一般用来压缩文本和程序文件。
哈夫曼压缩属于可变代码长度算法一族。
意思是个体符号(例如,文本文件中的字符)用一个特定长度的位序列替代。
因此,在文件中出现频率高的符号,使用短的位序列,而那些很少出现的符号,则用较长的位序列。
哈夫曼树与哈夫曼树编码实验原理
哈夫曼树与哈夫曼树编码实验原理哈夫曼树(Huffman Tree)是一种用于数据压缩的树形数据结构。
它的主要原理是通过构建一个最优的二叉树来实现编码和解码的过程。
以下是哈夫曼树和哈夫曼编码的实验原理:1. 构建哈夫曼树:- 给定一组需要进行编码的字符及其出现频率。
通常,这个频率信息可以通过统计字符在原始数据中的出现次数来得到。
- 创建一个叶节点集合,每个叶节点包含一个字符及其对应的频率。
- 从叶节点集合中选择两个频率最低的节点作为左右子节点,创建一个新的父节点。
父节点的频率等于左右子节点频率的和。
- 将新创建的父节点插入到叶节点集合中,并将原来的两个子节点从集合中删除。
- 重复上述步骤,直到叶节点集合中只剩下一个节点,即根节点,这个节点就是哈夫曼树的根节点。
2. 构建哈夫曼编码:- 从哈夫曼树的根节点开始,沿着左子树走一步就表示编码的0,沿着右子树走一步表示编码的1。
- 遍历哈夫曼树的每个叶节点,记录从根节点到叶节点的路径,得到每个字符对应的编码。
由于哈夫曼树的构建过程中,频率较高的字符在树中路径较短,频率较低的字符在树中路径较长,因此哈夫曼编码是一种前缀编码,即没有任何一个字符的编码是其他字符编码的前缀。
3. 进行数据压缩:- 将原始数据中的每个字符替换为其对应的哈夫曼编码。
- 将替换后的编码串连接起来,形成压缩后的数据。
4. 进行数据解压缩:- 使用相同的哈夫曼树,从根节点开始,按照压缩数据中的每个0或1进行遍历。
- 当遇到叶节点时,就找到了一个字符,将其输出,并从根节点重新开始遍历。
- 继续按照压缩数据的编码进行遍历,直到所有的编码都解压为字符。
通过构建最优的哈夫曼树和对应的编码表,可以实现高效的数据压缩和解压缩。
频率较高的字符使用较短的编码,从而达到减小数据大小的目的。
而频率较低的字符使用较长的编码,由于其出现频率较低,整体数据大小的增加也相对较小。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
为什么?
3 图像的无失真编码方法
自适应WBS编码
根据图像局部结构或统计特性,改变像素块 尺寸大小; 一维情况下,首先判断该行是否有1024个连 续白像素; 否则判断是否有64,16,4个连续白像素; 否则直接编码;
3 图像的无失真编码方法
1)白块跳过编码WBS
原理
对于一般白纸黑字的文件,总是白的面积大。因此 跳过白的行程,只对黑行程编码就可以压缩数据。 将每一扫描行分成若干段,每段包含n个像素。对 于全白段,给最短码字如0;而对于黑白相间或全 黑段,不进行压缩。 为区别全白段和有黑段,在编码前加1作为标志位。
一维WBS编码
3 图像的无失真编码方法
一维WBS编码平均码长
设全白段出现的概率是pw,则平均码长 1 1 Rn pw 1 1 pw n 1 1 pw n n 因此WBS 编码的效率取决于n和pw。
设n 5,求包含一个全白块、有黑块11010、 有黑块10000三块的WBS码。 解:全白块编码为0,有黑块11010编码为 111010,有黑块10000编码为110000, 所以编码为0111010110000。
从Lenna和Bob的差分图像的直方图看:
i 1 k i k 1
wn分成两组,
p;
i
n
Step 2 : 将两个子集分别编码0和1; Step3: 将两个子集重复Step1,同样上面子集编码0,下面编码1; Step 4 : 重复Step3,直到每个子集只有1个w为止。最后将编码依 次排出,得到Fano - Shannon编码。
2 பைடு நூலகம்损压缩技术
又称为信息保持编码。要求编码—解码过程中能够 无误差的重建图像。如在医学图像应用中。 常被称为保真度编码。常用在图像的信宿为人眼的 应用中,如数字电视、可视电话等。 是另一种有损编码。常用在图像的信宿为计算机的 应用中,这是只需要保留计算机处理的信息特征。 如图像识别。
(2)有损编码
(3)特征抽取编码
例:设输入w1 , w2 , w3 , w4 , w5 , w6的相应输入概率分别为 0.4,0.3,0.1,0.1,0.06,0.04,则Huffman编码可下图表示。
Ê ä È ë w1 w2 w3 w4 w5 w6 Å Â ¸ Ê 0.4 1 0.4 0.3 0.1 0.1 1 00 011 0.4 0.3 1 00 0.4 1 0.6 0.4 0 1
希望连续的0/1出现的概率增大.
Lena图像的比特平面
3 图像的无失真编码方法
问题:采样自然二进制码,将导致数据相关性减小。 如灰度127和128,对应自然二进制码分别为 01111111和10000000。较小的灰度变化导致比 特平面的突变。
解决方法:采用格雷码(Gray)。
若自然二进制码bk 1bk 2 b1b0 , 对应格雷码 gk 1 gk 2 g1 g0,则g k 1 bk 1 gi bi 1 bi
1)基本思想
2)预测误差的熵编码
3)DPCM预测编码
4)最佳线性预测
5)有失真预测编码
6)最佳量化
4 预测压缩技术
1)基本思想
图像相邻像素间存在很强的相关性,通过观察其相 邻像素取值,可以预测一个像素的大概情况。
预测值和实际值存在误差,称为预测误差。 预测误差的方差必然比原图像像素的方差小,因此 对预测误差进行编码必然压缩其平均码长。
对预测误差进行编码的技术称为DPCM(差分脉冲 编码调制)。
请结合熵的定义 思考这个结论
4 预测压缩技术
2)预测误差的熵编码
对比一幅图像和其差分图像的标准差和熵。
H p Di log 2 p Di
i 0 255
Lenna图象的标准差=47.94, H 7.45 Lenna差分图象的标准差=6.94, H 4.56
k 1 M
平均码字长度:设 k 是数字图象第k 个码字Ck的长度, 则图象的平均码字长度R定义为: R k Pk
k 1 M
编码效率 H 。 R
2 无损压缩技术
2)变长最佳编码定理和唯一可译代码
定理:在变长编码中,对出现概率大的信息符号赋予短码字, 而对于出现概率小的信息符号赋予长码字。可以证明,如果 码字长度严格按概率大小的逆序排列,则平均码字长度一定 小于任何其他排列方式。 唯一可译编码:如果码字之间不加同步码,则要求编码序列 唯一可译。 非续长代码:任何码字不能在其后面添加码元而形成其他码 字,称为非续长代码。 单义代码:任意有限长码字序列,只能唯一地分割成一个个 码字。其充要条件是 2- k 1。非续长代码一定是单义代码,
Fano-Shannon编码讨论 (1) Fano-Shannon编码是唯一可译码。短的码 不会成为更长码的启始部分; (2) Fano-Shannon编码的平均码长接近于熵; 编码效率略低于Huffman编码。
H pi log 2 pi 0.4log 2 0.4 0.3log 2 0.3 0.1log 2 0.1
(2)行程采用Huffman编码; (3)0-63之间的行程,用单个码字即终止码表 示; (4)大于63的游长用一个形成码和一个终止码组 合表示。形成码表示实际行程对64的倍数; (5)G3能达到15:1的压缩比; (6)G4采用二维行程程度编码,压缩比比G3提高 30%。
4 预测压缩技术
3 图像的无失真编码方法
自然二进制 码 000 格雷码 000 自然二进制码 100 格雷码 110
001
010 011
001
011 010
1
101
110 111
1 1 1 1
111
101 100
127
灰度图像 1 0 1
比特平面
3 图像的无失真编码方法
4)传真国际标准G3和G4
(1)G3采用一维行程长度编码;
在每一行编码前要加上N为多少的代码。
自适应WBS编码可以有效增加图像的 压缩 比,但增加了编码设备的复杂性。
3 图像的无失真编码方法
2)行程长度编码(RLC,Run-Length Coding)
原理:二值图像从左到右扫描图像时,连续白点和 连续黑点总是交替出现。将连续像素的数目称为行 程长度(Run-Length),分别为白长和黑长。 方法:统计所有行程长度出现的概率,然后采用 Huffman编码。
0.3 00 0.1 0.1 011 0100
0.3 00
010 01 0.2 0.3 0.1 011
0100
01010 0.06 0.1 0101 0.04 01011
2 无损压缩技术
Huffman压缩编码步骤: Step1: 把概率按大小从上到下排序; Step 2 : 把最下面两个概率相加,再重新排序; Step3: 重复Step 2,直到只有两个概率为止; Step 4 : 从右向左开始编码。每遇到分叉则在后补位;上叉补0, 下叉补1。
3 图像的无失真编码方法
1)白块跳过编码WBS
2)行程长度编码
3)比特平面编码
4)二值图像编码的国际标准G3和G4
3 图像的无失真编码方法
0)压缩比
直接编码一幅图像所需比特数取决于幅面大小及分 辨率。 设C为采用某种方法编码前后的 压缩比
图象直接编码所需比特 c 用某种方法编码所需比特
i 1 6
2.2bit
(3)缺点:与计算机的数据结构不匹配; (4)缺点:需要多次排序,耗费时间。
2 无损压缩技术
Huffman编码
Huffman编码最优性 扩展Huffman编码 自适应Huffman编码
Will be learnt in Multimedia Technology (请课后自学……)
i 1 6
0.1log 2 0.1 0.06log 2 0.06 0.04log 2 0.04 2.1435bit R i pi 0.4 1 0.3 2 0.1 4 0.1 4 0.06 4 0.04 4
i 1 6
2.2bit
例
3 图像的无失真编码方法
常用图像WBS编码平均码长
英文课文 英文文件 电路图 熵=0.15 熵=0.06 平均码长=0.3 平均码长=0.19 平均码长=0.39
熵=0.11
平均码长=0.25
气象形势图
熵=0.22
3 图像的无失真编码方法
二维WBS编码
将图像分成M*N大小的块,全白块以0编码, 其他同一维WBS编码。
1 序言
3)图像压缩编码的具体方法
(1)熵编码:信息保持编码;
(2)预测法:信息保持编码、保真度编码(更常 用); (3)变换法:特征保持编码; (4)其他编码法
2 无损压缩技术
1)基本概念
图象熵 Entropy :设图象每个灰度级出现的频率 对应的概率分别为P 1,P 2, P M 。则图象的熵定义为 H Pk log 2 Pk