本实验包含大量结构体的用法,需要先了解struct(自定数据类型),typedef(数据类型 别名),union(共用体)的用法。先参考《21天学通C语言 第六版》的第十一章
一、实验原理
1. Huffman编码算法
(1)将文件以ASCII字符流的形式读入,统计每个符号的发生频率;
(2)将所有文件中出现过的字符按照频率从小到大的顺序排列;
(3)每一次选出最小的两个值,作为二叉树的两个叶子节点,将和作为它们的根节点,这两个叶子节点不再参与比较,新的根节点参与比较;
(4)重复3,直到最后得到和为1的根节点;
(5)将形成的二叉树的左节点标0,右节点标1,把从最上面的根节点到最下面的叶子节点途中遇到的0, 1序列串起来,得到了各个字符的编码表示。
2. Huffman编码的数据结构设计
在程序实现中使用一种叫做二叉树的数据结构实现Huffman编码。
(1)霍夫曼节点结构
typedef struct huffman_node_tag //节点数据类型
{
unsigned char isLeaf; //是否为叶节点,1是0否
unsigned long count; //信源文件中出现频数
struct huffman_node_tag *parent; //父节点指针
union
{
struct //如果不是叶节点,那么它为该节点左右子节点的指针
{
struct huffman_node_tag *zero, *one;
};
unsigned char symbol; //如果是叶节点,那么它表示某个信源符号,这里用一个字节的8位二进制数表示
};
} huffman_node;
(2)霍夫曼码结构
typedef struct huffman_code_tag //码字数据类型
{
unsigned long numbits; //码字的长度(bit)
/* 因为unsign char 类型是以 8 bit 来保存数据,所以码字8个8个一组保存在bits[]中,
例: 码字的第1位存于bits[0]的第1位,
码字的第2位存于bits[0]的第的第2位,
码字的第8位存于bits[0]的第的第8位,
码字的第9位存于bits[1]的第的第1位 */
unsigned char *bits; //指向该码比特串的指针
} huffman_code;
3霍夫曼编码流程
该程序包括两个工程,“huff_run”为主工程,其中包括了“huffcode.c”文件
“Huff_code”为库工程,其中包括了“huffman.c”文件
下面按照实验流程来进行分析
3.1 读入待编码的源文件
如下代码属于”huffcode.c”文件
main(int argc, char** argv)
{
char memory = 0; //memory为1表示对内存数据进行操作,0表示不操作
char compress = 1; //compress为1表示编码,0表示解码
int opt;
const char *file_in = NULL, *file_out = NULL;
//step1:add by yzhang for huffman statistics
const char *file_out_table = NULL;
//end by yzhang
FILE *in = stdin;
FILE *out = stdout;
//step1:add by yzhang for huffman statistics
FILE * outTable = NULL; //输出的中间数据的表
//end by yzhang
while((opt = getopt(argc, argv, "