【数据结构】哈夫曼编码

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

typedef struct{
	unsigned int weight;		//权值
	unsigned int parent , lchild , rchild;		//父节点,左子树,右子树
}HTNode, *HuffmanTree;			//动态分配数组存储赫夫曼树

typedef char ** HuffmanCode;	//动态分配数组存储赫夫曼编码表

unsigned int min1,min2;

void Select(HuffmanTree &HT,int i,int &s1,int &s2)
{
	min1=min2=32767;
	s1=s2=0;
	int j;
	for(j=1;j<=i;j++)
	{
		if(HT[j].weight<min1&&!HT[j].parent)
		{
			min2=min1;
			s2=s1;
			min1=HT[j].weight;
			s1=j;
		}
		else if(HT[j].weight<min2&&!HT[j].parent)
		{
			min2=HT[j].weight;
			s2=j;
		}
	}
}
void HuffmanCoding(HuffmanTree &HT,HuffmanCode &HC,int *w,int n){
	//w存放n个字符的权值,构造赫夫曼树HT,并求出n个字符的赫夫曼编码HC
	int m;//m表示赫夫曼树总共结点
	int i;
	int s1=0;
	int s2=0;
	HuffmanTree p;
	char *cd;
	unsigned int start,c,f;
	if(n<=1)
		return;
	m = 2*n -1 ;	//节点数
	HT = (HuffmanTree)malloc((m+1)*sizeof(HTNode));	//分配存储空间,0号单元未用
	for(p = HT+1,i=1;i<=n;++i,++p){
		p->weight = w[i];
		p->parent = 0;
		p->lchild = 0;
		p->rchild = 0;
	}
	for(i=n+1;i<=m;++i,++p){
		p->weight = 0;
		p->parent = 0;
		p->lchild = 0;
		p->rchild = 0;
	}
		
	for(i=n+1;i<=m;++i){		//建赫夫曼树
		//在HT[1...i-1]选择parent为0且weight最小的两个结点,其序号分别为是s1和s2
		Select(HT,i-1,s1,s2);
		HT[s1].parent = i;
		HT[s2].parent = i;
		HT[i].lchild = s1;
		HT[i].rchild = s2;
		HT[i].weight = HT[s1].weight + HT[s2].weight;
	}
	for(i=1;i<=m;i++)
		printf("%d,%d,%d,%d\n",HT[i].weight,HT[i].parent,HT[i].lchild,HT[i].rchild);
	//从叶子到根逆向求每个字符的赫夫曼编码
	HC = (HuffmanCode)malloc((n+1)*sizeof(char *));	//分配n个字符编码的头指针向量
	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';
		HC[i] = (char *)malloc((n-start)*sizeof(char));
		strcpy(HC[i],&cd[start]);		//
	}
	free(cd);
}
void main(){
	int n;
	int NT[100];
	int i;
	HuffmanTree HT;
	HuffmanCode HC;
	printf("请输入你的赫夫曼树的叶子结点个数:\n\n");
	scanf("%d",&n);
	for(i=1;i<=n;i++)
	{
		printf("输入第 %d 个数字的权重",i);
		scanf("%d",&NT[i]);
	}
	HuffmanCoding(HT,HC,NT,n);
	printf("赫夫曼树编码如下:\n\n");
	for(i=1;i<=n;i++)
	{
		printf("%d :%s\n",HT[i].weight,HC[i]);
	}
	printf("\n\n");
}



By Mr.Z

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值