huffman编解码算法实验与压缩效率分析

一、基本原理

1、huffman编码原理

huffman编码是一种无失真编码方式,是可变长(VLC)编码的一种。

huffman编码基于信源的概率统计模型,基本思路是出现概率大的信源符号编长码,出现概率小的符号编短码,从而使平均码长最小。

2、数据结构

在本实验中的数据结构中,用到了两个数据结构:

在程序实现过程中,使用了一种二叉树的数据结构,由它编出的码是即时码。树是一种重要的非线性数据结构,直观的看,它是数据元素(在树中称为结点)按分支关系组织起来的结构。在计算机科学中,二叉树是每个结点最多有两个字树的有叙树,常用来实现查找或排序。

二叉树的两个子树有左右之分,次序不能颠倒,二叉树的第i层至多有2^(i-1)个结点;深度(二叉树的层数)为k的二叉树至多有2^(k)-1个结点。

树的表示方法有许多,最常用的是:(a(b(c,d),e(d,e(……));(先将根结点放入一对圆括号中,然后把它的子树由左至右的顺序放入括号中,同层子树之间用逗号隔开。

树的遍历是对二叉树的一种最基本的操作,通过访问二叉树的所有节点,将二叉树转换为一个线性序列。

3、对内存数据编解码

待添加。(本实验未涉及)

二、流程分析

1、项目框架

本实验由两个项目组成:huff_code(静态库)和huff_run(win32控制台项目)

静态库的配置(方法一:):huff_code是一个静态库,不能直接运行,在vs中点生成->生成解决方案,在debug文件夹下找到huff_code.lib文件,连同huffman.h拷贝至huff_run文件项目文件夹下,在huff_run的main函数之前添加#include<huff_code.lib>和#include<huffman.h>.以及#pragma comment(lib,"huff_code.lib")//这是告诉编译器在编译形成的.obj件和.exe文件中加一条信息,使得 链接器在链接库的时候要去找wsock32.lib这个库,不要先去找别的库。

方法二:在debug文件夹下找到huff_code.lib文件,连同huffman.h拷贝至huff_run文件项目文件夹下,在huff_run的main函数之前添加#include<huff_code.lib>,设置huff_run的项目属性,在vc++目录的包含目录里添加huffman.h的所在的路径,库目录里加入huff_code.lib所在的路径,在连接器->输入->附加依赖项->输入“huff_code.h”。

2、程序框架

2.1编码流程

1)将文件以ASCII字符流的形式读入,统计每个符号发生的概率

(2)将文件中所有出现过的字符概率从小到大进行排列

(3)每一次选出最小的两个值,作为二叉树的两个叶子节点,将他们的和作为根节点,这两个叶子节点不再参与比较,新的根节点参与比较

(4)重复三,直到得出和为1的根节点

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

2.2解码流程

1)读取码表并重建huffman树

(2)读取huffman码字,并解码输出

三、关键代码分析

1、头文件

int huffman_encode_file(FILE *in, FILE *out,FILE *out_Table);//step1: changed by yzhang for huffman statistics
int huffman_decode_file(FILE *in, FILE *out);
int huffman_encode_memory(const unsigned char *bufin,
						  unsigned int bufinlen,
						  unsigned char **pbufout,
						  unsigned int *pbufoutlen);
int huffman_decode_memory(const unsigned char *bufin,
						  unsigned int bufinlen,
						  unsigned char **bufout,
						  unsigned int *pbufoutlen);
通过调用四个函数完成对输入文件以及内存里文件的编、解码工作。在huffman_encoder_file的函数接口里添加FILE *outTable,用来输出编码的相关信息。

2、主函数(huffcode.c->)

int main(int argc, char** argv)
{
	char memory = 0;//0表示不对内存数据操作,1表示对内存数据操作
	char compress = 1;//压缩编码为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)//读命令行参数选项,argc和argv代表代表参数个数和内容,参数 optstring为选项字符串, 告知 getopt()可以处理哪个选项以及哪个选项需要参数,
		//如果选项字符串里的字母后接着冒号":",则表示还有相关的参数,全域变量optarg 即会指向此额外参数。
	{
		 printf("opt:%c ",opt);
		switch(opt)
		{
		case 'i'://输入文件,有相关参数
			file_in = optarg;
			break;
		case 'o'://输出文件,有相关参数
			file_out = optarg;
			break;
		case 'c'://编码
			compress = 1;
			break;
		case 'd'://解码
			compress = 0;
			break;
		case 'h'://输出帮助信息
			usage(stdout);
			return 0;
		case 'v'://输出版本信息
			version(stdout);
			return 0;
		case 'm'://对内存编码或解码
			memory = 1;
			break;
		// by yzhang for huffman statistics
		case 't'://输出编解码信息表格
			file_out_table = optarg;//			
			break;
		//end by yzhang
		default:
			usage(stderr);
			return 1;
		}
	}
  • 1
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值