自适应哈夫曼编解码

本文详细介绍了自适应哈夫曼编码的原理和流程,包括如何根据编码过程中符号权重的变化动态调整编码树。通过具体的数据结构如`Node`和`HuffmanTree`,阐述了节点编号、兄弟属性以及调整方法。此外,还展示了编码和解码过程,解释了如何处理新符号的插入以及如何保持编码树的合法性和效率。最后,给出了完整的Java实现代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.实验原理

自适应哈夫曼编码这种方案在不需要事先构造 Huffman 树,而是随着编码的进行,逐步构造 Huffman 树。随着编码的进行,同一个符号的权重发生改变,此时原有的Huffman编码树已经不一定符合具有最小加权路径这一条件,因此必须调整编码树,保持其合法Huffman编码树的状态。

在说明调整方法之前,先给每个节点引入两个新的属性:“节点编号”和“所属块”。节点编号时全局一个唯一的值,根节点的编号最大,向左和向下递减。如下图:

“块”是指具有相同权重的一组结点。

在构造动态霍夫曼编码树的过程中,需要遵循两条重要原则:

(1)权重值大的节点,节点编号也较大。

(2)父节点的节点编号总是大于子节点的节点编号。

以上两点称为兄弟属性(sibling property)。在每一次调整节点权重值时,都需要相应的调整节点编号,以避免兄弟属性被破坏。在对某一个节点权重值进行“加一操作”时,应该首先检查该节点是否具有所在的块中的最大节点编号,如果不是,则应该将该节点与所在块中具有最大节点编号的节点交换位置。然后再对节点的权重值加。这样,由于该节点的节点编号已经处于原来所属块中的最大值,因此权重值加一之后兄弟属性仍然得到满足。最后,由于节点的权重发生了变化,必须递归地对节点的父节点进行加一操作。

初始化编码树时,编码树的初始状态只包含一个叶节点,包含符号 NYT(Not Yet Transmitted,尚未传送),权重值为 0。 NYT是一个逸出码(escape code),不同于任何一个将要传送的符号。当有一个尚未包含在编码树中的符号需要被编码时,系统就输出 NYT 编码,然后跟着符号的原始表达。当解码器解出一个 NYT 之后,它就知道下面的内容暂时不再是 Huffman 编码,而是一个从未在编码数据流中出现过的原始符号。这样,任何符号都可以在增加到编码树之前进行传送。

在需要插入一个新符号时,总是先构造一个新的子树,子树包含NYT 符号与新符号两个叶节点,然后将旧的NYT 节点由这个子树替代。由于包含NYT 符号的节点权重值为0,而包含新符号的叶节点的权重值为1,因此最终效果相当于原NYT 节点位置的权重值由0 变为1。因此,下一步将试图对其父节点执行权重值“加一操作”。

对符号编码的方法与静态霍夫曼编码一致,每次符号编码完成以后,也将对包含符号的节点权值进行加一操作。

将一个新的符号插入编码树或者输出某一个已编码符号后,相应的符号的出现次数增加了1,继而编码树中各种符号的出现频率发生了改变,不一定符合兄弟属性,按照上述方法进行调整,使其符合要求。

2. 实验流程

这是别人的流程图,也可以参考。

3.数据结构

Node

public class Node {

       public char letter;     // the character of each code

       public int count; // 权重

       public int left;    // the left child of each node

       public int right;  // the right child of each node

       public int parent;      // the parent of each node

}

HuffmanTree

自适应霍夫曼编码的C++版本简单实现 class AdaptiveTree { public: AdaptiveTree(int rootNum); AdaptiveTree(int rootNum, string str); void swap(int first, int second); // swap two nodes of the tree void initalCode(); // initializing the data string char2code(unsigned char letter); // locate the character in the tree with its corresponding binary string and return the string string char2binary(unsigned char letter); // translating the character to the 8-bit binary string unsigned char binary2char(string bin); // translating the binary string: bin to the corresponding character int spawn(unsigned char letter); // add a new character to the original tree void updateTree(unsigned char newchar); // update the tree int highestInBlock(int count); // return the highest node to be exchanged void setString(string str); // string decodingStr() const; void encoding(); string decoding(); unsigned char code2char(string bincode); static int size(); string binStr() const; // return the binary string of string: tempString private: void run(); int findchar(unsigned char letter ); // locate the letter in the tree string tempString; //temp string to be encoded needed to be stored here string deStr;// used for storing the decoding string string bin; // used for storing the result of encoding process /* Adaptive Tree data members */ HuffmanTree *tree; int root; /* Adaptive Tree constants */ static int ALPH_SIZE; // size of the alphabet static unsigned char none; // not a unsigned character static unsigned char NYT; // Not Yet transmitted code };
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值