数据压缩实验三:Huffman编解码

一、基本原理

1.Huffman编码算法

()统计频率:将文件以ASCII字符流的形式读入,统计每个符号的发生频率;

2)排序:将所有文件中出现过的字符按照频率从小到大的顺序排列;

3)每一次选出最小的两个值,作为二叉树的两个叶子节点,将和作为它们的根节点,这两个叶子节点不再参与比较,新的根节点参与比较;重复此步骤,直到最后得到和为1的根节点;

4)编码:将形成的二叉树的左节点标0,右节点标1,把从最上面的根节点到最下面的叶子节点途中遇到的0、1序列串起来,得到了各个字符的编码表示。

2.Huffman编码的数据结构设计

1)Huffman节点结构

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;//指向子节点,左0右1
		};
		unsigned char symbol;//如果是叶节点,则为某个信源符号
	};
} huffman_node;

2)Huffman码结构

typedef struct huffman_code_tag
{
	/* The length of this code in bits. */
	unsigned long numbits;//码字的长度

	/* 码字的第1位存于bits[0]的第1位,
	码字的第2位存于bits[0]的第2位,
	码字的第8位存于bits[0]的第8位,
	码字的第9位存于bits[1]的第1位*/
	unsigned char *bits;
} huffman_code;

二、实验流程及代码分析

1.Huffman编码流程


(1)读入待编码的源文件

int
main(int argc, char** argv)
{
	char memory = 0;//是否对内存数据进行操作,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

	/* Get the command line arguments. */
	while((opt = getopt(argc, argv, "i:o:cdhvmt:")) != -1) //读取命令行参数
	{
		switch(opt)
		{
		case 'i':
			file_in = optarg;//i 输入文件
			break;
		case 'o':
			file_out = optarg;//o 输出文件
			break;
		case 'c':
			compress = 1;//c 编码
			break;
		case 'd':
			compress = 0;//d 解码
			break;
		case 'h':
			usage(stdout);//h 输出参数用法的说明
			return 0;
		case 'v':
			version(stdout);//v 输出版本号的信息
			return 0;
		case 'm':
			memory = 1;//m 对内存数据进行操作
			break;
		// by yzhang for huffman statistics
		case 't':
			file_out_table = optarg;//t 输出中间数据信息			
			break;
		//end by yzhang
		default:
			usage(stderr);
			return 1;
		}
	}

	/* If an input file is given then open it. */
	if(file_in)//读取输入文件
	{
		in = fopen(file_in, "rb");
		if(!in)
		{
			fprintf(stderr,
					"Can't open input file '%s': %s\n",
					file_in, strerror(errno));
			return 1;
		}
	}

	/* If an output file is given then create it. */
	if(file_out)//创建输出文件
	{
		out = fopen(file_out, "wb");
		if(!out)
		{
			fprintf(stderr,
					"Can't open output file '%s': %s\n",
					file_out, strerror(errno));
			return 1;
		}
	}

	//by yzhang for huffman statistics
	if(file_out_table)
	{
		outTable = fopen(file_out_table, "w");
		if(!outTable)
		{
			fprintf(stderr,
				"Can't open output file '%s': %s\n",
				file_out_table, strerror(errno));
			return 1;
		}
	}
	//e
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值