哈夫曼编码实现

本文介绍了一种基于C++实现哈夫曼编码的方法,通过构建哈夫曼树来实现字符的最短编码。文章首先解释了哈夫曼编码的概念,即根据字符出现频率构建前缀编码,确保编码的最优化。接着,展示了如何用C++代码构建哈夫曼树并生成编码。程序中包含了创建哈夫曼树、选择最小和次小节点的函数,以及哈夫曼编码的动态分配和存储。最后,给出了一个实例,演示如何对给定字符频率进行编码。
摘要由CSDN通过智能技术生成

哈夫曼编码也称前缀编码,它是根据每个字符出现的频率而进行编码的,要求任一字符的编码都不是其它任意字符编码的前缀且字符编码的总长度为最短。它主要应用于通信及数据的传送以及对信息的压缩处理等方面。哈夫曼编码的基础是依据字符出现的频率值而构造一棵哈夫曼树,从而实现最短的编码表示最常用的数据块或出现频率最高的数据。

某个信息所含的五种字符的出现次数分别为: 

a - 16,b - 7,c - 6,d - 6,e - 5.  现要求对这五种字符进行哈夫曼编码。

 

#include<stdio.h>
#include<string.h>
#include<malloc.h>
#define MAX 100
//哈夫曼树结点结构体
typedef struct{
	int weigth;
	int parent;
	int rchild;
	int lchild;
}HTNode,*HuffmanTree;
//需要编码的字符串数组
static char N[MAX];
//定义哈夫曼编码数组(char型二级指针(指向指针的指针))
typedef char **HuffmanCode;
//最小与次小的结点
typedef struct{
	int s1;
	int s2;
}MinCode;
//函数声明
MinCode Select(HuffmanTree HT,int n);
//哈夫曼树,哈夫曼编码,权值数组,叶子结点数量
HuffmanCode HuffmanCoding(HuffmanTree HT,HuffmanCode HC,int *w,int n){
	int i,s1=0,s2=0;
	//哈夫曼树
	HuffmanTree p;
	//暂存哈夫曼编码数组
	char *cd;
	int f,c,start,m;
	//最小与次小节点
	MinCode min;
	//m为总结点数
	m=2*n-1;
	//动态创建哈夫曼树
	HT=(HuffmanTree)malloc((m+1)*sizeof(HTNode));
	//HT前n个为叶子节点,后面n-1个为非叶子节点
    //初始化n个叶子节点
	for(p=HT,i=0;i<=n;i++,p++,w++){
		p->weigth=*w;
		p->parent=0;
		p->rchild=0;
		p->lchild=0;
	}
	//初始化从后面数n-1个非叶子节点
	for(;i<=m;i++,p++){
		p->weigth=0;
		p->parent=0;
		p->lchild=0;
		p->rchild=0;
	}
	//创建哈夫曼树
	for(i=n+1;i<=m;i++){
		//寻找最小与次小
		min=Select(HT,i-1);
		s1=min.s1;
		s2=min.s2;
		//合并树
		HT[s1].parent=i;
		HT[s2].parent=i;
		HT[i].lchild=s1;
		HT[i].rchild=s2;
		HT[i].weigth=HT[s1].weigth+HT[s2].weigth;//合并权值
	}
	//输出创建的树
	printf("哈夫曼树列表:\n");
	printf("序号\t权值\t父节点\t左孩子\t右孩子\n");
	for(i=1;i<=m;i++)
		printf("%d\t%d\t%d\t%d\t%d\n",i,HT[i].weigth,HT[i].parent,HT[i].lchild,HT[i].rchild);
	//动态创建哈夫曼编码
	HC=(HuffmanCode)malloc((n+1)*sizeof(char *));
	//动态创建暂存哈夫曼编码数组
	cd=(char *)malloc(n*sizeof(char *));
	//最后一位赋值为结束符
	cd[n-1]='\0';
	for(i=1;i<=n;i++){
		start=n-1;
		//从第一号结点往上回溯查找,逆序存放
		for(c=i,f=HT[i].parent;f!=0;c=f,f=HT[f].parent){
			//父节点的左子树与自己比较
			if(HT[f].lchild==c)
				cd[--start]='0';
			else
				cd[--start]='1';
		}
		//对第i个字符分配空间
		HC[i]=(char *)malloc((n-start)*sizeof(char *));
		//将cd暂存的复制到HC
		strcpy(HC[i],&cd[start]);
	}
	free(cd);
	return HC;
}
//选出最小与次小的函数
MinCode Select(HuffmanTree HT,int n){
	int min,secmin;
	int i,s1,s2;
	MinCode code;
	s1=1;
	s2=1;
	min=0x3f3f3f3f;
	for(i=1;i<=n;i++){
		if(HT[i].weigth<min && HT[i].parent==0){
			min=HT[i].weigth;
			s1=i;
		}
	}
	secmin=0x3f3f3f3f;
	for(i=1;i<=n;i++){
		if((HT[i].weigth<secmin) && (i!=s1) && HT[i].parent==0){
			secmin=HT[i].weigth;
			s2=i;
		}
	}
	code.s1=s1;
	code.s2=s2;
	return code;
}
int main(){
	HuffmanTree HT=NULL;
	HuffmanCode HC=NULL;
	int *w=NULL;
	int i,n;
	printf("请输入要编码的字符串:");
	gets(N);
	n=strlen(N);
	w=(int *)malloc((n+1)*sizeof(int *));
	w[0]=0;
	printf("依次输入权值:\n");
	for(i=1;i<=n;i++){
		printf("w[%d]=",i);
		scanf("%d",&w[i]);
	}
	HC=HuffmanCoding(HT,HC,w,n);
	printf("哈夫曼编码:\n");
	printf("字符\t权值\t编码\n");
	for(i=1;i<=n;i++)
		printf("%c\t%d\t%s\n",N[i-1],w[i],HC[i]);
	printf("哈夫曼编码:\n");
	for(i=1;i<=n;i++)
		printf("%s\t",HC[i]);
	printf("\n");
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

未满3岁

我爱你,你爱我,蜜雪冰城甜蜜蜜

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值