RLE 行程长度压缩算法
RLE(Run Length Encoding)行程长度压缩算法(也称游程长度压缩算法),是最早出现、也是最简单的无损数据压缩算法。
RLE算法的基本思路是把数据按照线性序列分成两种情况:
一种是连续的重复数据块,另一种是连续的不重复数据块。
对于第一种情况,对连续的重复数据块进行压缩,压缩方法就是用一个表示块数的属性加上一个数据块代表原来连续的若干块数据。对于字符串“AAABBBBBCD”,用这种RLE算法Rle_Encode_N()函数压缩后的数据就是:0x03,0x41,0x05,0x42,0x01,0x43,0x01,0x44共8个字节,比原始长度10个字节少了2个字节,实现了数据长度的压缩。
对于第二种情况,RLE算法有两种处理方法,一种处理方法是用和第一种情况一样的方法处理连续的不重复数据块,仅仅是表示块数的属性总是1;另一种处理方法是不对数据进行任何处理,直接将原始数据作为压缩后的数据。
是Zero suppression消零的一般化,假定了一个符号一直出现。
Shannon-Fano Algorithm香农-范诺算法
Shannon-Fano的树是根据旨在定义一个有效的代码表的规范而建立的。实际的算法很简单:
对于一个给定的符号列表,制定了概率相应的列表或频率计数,使每个符号的相对发生频率是已知。
排序根据频率的符号列表,最常出现的符号在左边,最少出现的符号在右边。
清单分为两部分,使左边部分的总频率和尽可能接近右边部分的总频率和。
该列表的左半边分配二进制数字0,右半边是分配的数字1。这意味着,在第一半符号代都是将所有从0开始,第二半的代码都从1开始。
对左、右半部分递归应用步骤3和4,细分群体,并添加位的代码,直到每个符号已成为一个相应的代码树的叶。
这个例子展示了一组字母的香浓编码结构(如图a所示)这五个可被编码的字母有如下出现次数:
item | |||||
---|---|---|---|---|---|
Symbol | A | B | C | D | E |
Count | 15 | 7 | 6 | 6 | 5 |
Probabilities | 0.38461538 | 0.17948718 | 0.15384615 | 0.15384615 | 0.12820513 |
从左到右,所有的符号以它们出现的次数划分。在字母B与C之间划定分割线,得到了左右两组,总次数分别为22,17。 这样就把两组的差别降到最小。通过这样的分割, A与B同时拥有了一个以0为开头的码字, C,D,E的码子则为1,如图b所示。 随后, 在树的左半边,于A,B间建立新的分割线,这样A就成为了码字为00的叶子节点,B的码子01。经过四次分割, 得到了一个树形编码。 如下表所示,在最终得到的树中, 拥有最大频率的符号被两位编码, 其他两个频率较低的符号被三位编码。
result | |||||
---|---|---|---|---|---|
符号 | A | B | C | D | E |
编码 | 00 | 01 | 10 | 110 | 111 |
Entropy(熵,平均码字长度):
Huffman Coding霍夫曼编码
先按照出现的概率或者频率大小排队,把两个最小的挑出俩来,把这两个概率或频率相加,再重新排队,直到最后变成一或者变成总频率。最后形成的树左边0右边1。
Adaptive Huffman Coding
在静态霍夫曼编码中,要构造编码树必须提前统计被编码对象中的符号出现频率,因此必须对输入符号流进行两遍扫描,第一遍统计符号出现频率并构造编码树,第二遍进行编码,这在很多实际应用的场合中是不能被接受的。
其次,在存储和传输霍夫曼编码时,必须先存储和传送霍夫曼编码树。
再次,静态编码树构造方案不能对输入符号流的局部统计规律变化做出反应。
这些问题使静态霍夫曼编码在实际中并没有得到广泛的应用。
由此,提出了自适应霍夫曼编码,这种方案不需要提前进行扫描输入符号流,而是随着编码进行的同时构造Huffman树,因此只需要进行一次扫描。在接收端伴随解码过程的同时进行着编码树的构造。解决了静态编码树所面临的主要问题,得到了广泛应用。
此方案不需要事先构造霍夫曼树,而是随着编码的进行,逐步构造霍夫曼树,同时对符号的统计也动态进行, 随着编码的进行,同一个符号的编码也可能发生改变(更长或更短)。
原理:
- 权重值大的节点,节点编号也较大。
- 父节点的节点编号总是大于子节点的节点编号。
这两点称为兄弟属性。
样例:
以abcddbb为待编码的原始数据串为例,自适应Huffman编码过程如下:
- 初始状态只有NYT节点,权重为0;
- 输入符号:a,输出编码:1
- 输入符号:b,输出编码:01;包含新NYT结点和字符b结点的子树替换旧的NYT结点。对51号结点(根节点)权重值加一
输入符号:c,输出编码:001。包含新NYT节点和字符c的子树,替换旧的NYT结点,49号结点权重加一,但49号结点不具有所在块中最大结点编号,需要先与50号结点进行位置交换。
所以