update tree
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
|
||||
## 赫夫曼编码 Huffman
|
||||
|
||||
这是一个经典的压缩算法。通过`字符出现的频率`,`优先级`,`二叉树`进行的压缩算法。
|
||||
|
||||
对一个字符串,计算每个字符出现的次数,把这些字符放到优先队列(priority queue)
|
||||
这这个priority queue转出二叉树
|
||||
|
||||
需要一个字符编码表来解码,通过二叉树建立huffman编码和解码的字典表
|
||||
|
||||
|
||||
原始串:
|
||||
二级制编码:
|
||||
huffman编码:
|
||||
|
||||
|
||||
### 存储结构和基本操作
|
||||
|
||||
```
|
||||
struct node{
|
||||
char *huffCode; // 叶子节点的huff编码
|
||||
int weight;
|
||||
struct node *left,right;
|
||||
}
|
||||
```
|
||||
|
||||
### 构建赫夫曼树
|
||||
|
||||
原则:出现频率越多的会在越上层,编码也越短,出现频率越少的在越下层,编码也越长。
|
||||
不存在某一个编码是另一个编码的前缀,字符都在叶节点上,所以不会存在一个编码是另一个编码的前缀
|
||||
二叉树每个节点要么是叶子节点,要么是双分支节点(且左分支编码为0,右分支编码为1)
|
||||
|
||||
|
||||
### 压缩
|
||||
|
||||
1. 扫描输入文件,统计各个字符出现的次数,对结构排序 (hash统计每个字符出现的次数)
|
||||
2. 根据排序结构,构建赫夫曼树 (贪心策略,每次选频率值最低的2个节点合并,需要优先队列帮组(priority queue,又叫最小堆))
|
||||
3. 对树进行遍历(左分支编码为0,右分支编码为1),得到各个字符的huffman编码,存到hash表中(这个就是编解码表,也可直接存储到节点中,如上面的char *huffCode)
|
||||
4. 重新对文件扫描,根据hash表进行压缩
|
||||
|
||||
压缩的文件为了能够解压缩,需要一个文件头,用来重建赫夫曼树,包括:
|
||||
被编码的文本长度 unsigned int size
|
||||
字符频率表 unsigned char freqs[NUM_CHARS]
|
||||
|
||||
###解压缩
|
||||
|
||||
1. 读取文件头
|
||||
2. 遍历编码后的bits,从赫夫曼树的根节点出发,遇到0,进入左子树,遇到1进入右子树,直到叶节点
|
||||
|
||||
Reference in New Issue
Block a user