目录
前言
这篇博客主要分享介绍我写的Huffman树的编码和译码系统,我写好的代码已经打包上传了,感兴趣的小伙伴可以下载玩一玩,还挺有意思的。
Huffman编码就是靠字符出现的频次作为权值构建Huffman树,然后通过左右分支形成编码,相关知识点我也放上了我讲这一块知识点的相关博客。
相关说明
作者:李宗霖
日期:2023年05月28日
两个头文件:"enhuffman.h" "dehuffman.h"
两个源文件:"enhuffman.c" "dehuffman.c"
enhuffman:Huffman编码
dnhuffman:Huffman译码
【注意】
1.我将访问的文件名以宏定义的方式放在源文件内,可以自行修改
默认: 读取huffman_test_file.txt ---> 编码 ---> 生成huffman_encoding_file.txt
读取huffman_encoding_file.txt ---> 译码 ---> 生成huffman_decoding_file.txt
2.我将一些测试健壮性的开关宏设置在了开头,方便调试程序可以自行打开关闭
3. void LookupDeFile(); 是dnhuffman程序入口,剩下的方法都是在这个函数内被调用
void ReadFile(); 是enhuffman程序入口,剩下的方法都是在这个函数内被调用
4.enhuffman采用顺序存储,构造使用的是我自己优化后的索引查找
5.dehuffman采用链式结构,构造是用先序遍历
相关知识点
在我的这篇博客里面介绍了最基本的Huffman树的相关操作:
数据结构 实验17:Huffman树和Huffman编码——学习理解哈夫曼树_Leisure_水中鱼的博客_CSDN博客
我的这一篇博客讲解了我对课本上顺序存储构造Huffman树方法的优化:
数据结构 深度学习索引结构——用索引算法优化课本哈夫曼树的构造算法_Leisure_水中鱼的博客_CSDN博客
代码测试
因为我两个头文件都是写好的,我也设置了相应的调用入口,主函数简单的写了个测试:
#include <stdio.h>
#include <stdlib.h>
#include "dehuffman.h"
#include "enhuffman.h"
int main() {
printf("输入以下字符进行操作:\n");
printf("'1':编码\n'2':译码\n'0':结束\n");
char c;
while (1) {
printf("\nEnter: ");
scanf(" %c", &c);
if (c == '0') {
break;
}
else if (c == '1') {
ReadFile(); //调用编码
}
else if (c == '2') {
LookupDeFile(); //调用译码
}
}
printf("\n----------Bye Bye----------\n");
return 0;
}
编码系统
这个是提前准备好的装有数据的txt文档,是网上随便复制的一篇作文,和随便打的一些字符:
为了方便调试我定义了一些开关,这是编码相关的开关:
//定义一些开关 0为关,1为开
#define LOOP_checkEnFileExists 1 //检测将生成文件的名是否存在,若是存在提问是否覆盖文件
#define LOOP_printHuffman 0 //是否在屏幕上打印创建出的哈夫曼树,打印后立即结束程序
#define LOOP_printFileEncoding 0 //是否在屏幕上打印出文件编码
#define LOOP_writeElemCode 0 //是否在文件中写入各个元素的编码
#define LOOP_printElemCode 0 //在写入元素编码开关打开的前提下是否在屏幕上打印
运行结果
运行后生成的文件
译码系统
定义的译码相关的开关:
//定义一些开关 0为关,1为开
#define LOOP_checkDeFileExists 1 //检测将生成文件的名是否存在,若是存在提问是否覆盖文件
#define LOOP_printFileDecoding 1 //是否在屏幕上打印文件译码后的内容
运行结果
写入的文件
其他测试
打开输出Huffman树的开关
0内存单元存的是根节点,双亲中存的是叶子结点数量。
打开写入元素编码并打印相关的开关