构建哈夫曼编码

本文介绍如何根据输入字符串中各字符的出现频率,详细步骤构建哈夫曼树,并生成对应的哈夫曼编码,以此实现高效的数据压缩。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

根据输入的字符串,计算字符的频率,构建哈夫曼编码

#include<iostream>
#include<string>
#include<map>
using namespace std;
typedef char ** HuffmandCode;
typedef struct node{
	int value;
	int left,right,parent;
}HTNode,*HuffmandTree;
void select(HuffmandTree HT,int end,int *s1,int*s2)
{
   int min1,min2;
   int i=1;
   while(HT[i].parent!=0&&i<=end)
   {
	   i++;
   }//要找到父节点为0的那些节点,她们还没构成树
   min1=HT[i].value;
   *s1=i;
   i++;
   while(HT[i].parent!=0&&i<=end)
   {
	   i++;
   }
  if(HT[i].value<min1)
  {
	  min2=min1;
	  *s2=*s1;
	  min1=HT[i].value;
	  *s1=i;
  }
  else{
	  min2=HT[i].value;
	  *s2=i;
  }

  for(int j=i+1;j<=end;j++)
  {
	  if(HT[j].parent!=0)
	    continue;
	  if(HT[j].value<min1)
	  {
		   min2=min1;
		  *s2=*s1;
		  min1=HT[j].value;
		  *s1=j;
	  }
	  else if(HT[j].value>=min1&&HT[j].value<min2)
	  {
		   min2=HT[j].value;
		  *s2=j;
	  }
  }
}
	  




void createHuffmand(HuffmandTree *HT,int *w,int n)
{
	if(n<=1)
		return;//只有一个编码
	int m=2*n-1;//哈夫曼树的节点数
	*HT=(HuffmandTree)malloc((m+1)*sizeof(HTNode));//0号位置不用
	HuffmandTree p=*HT;//初始化哈夫曼树
    for(int i=1;i<=n;i++)
	{
		(p+i)->value=*(w+i-1);
		(p+i)->parent=0;
		(p+i)->left=0;
		(p+i)->right=0;
	}
	for(i=n+1;i<=m;i++)
	{
		(p+i)->value=0;
			(p+i)->parent=0;
		(p+i)->left=0;
		(p+i)->right=0;
	}
    ///构建哈夫曼树
	for(i=n+1;i<=m;i++)
	{
		int s1,s2;
		select(*HT,i-1,&s1,&s2);
		(*HT)[s1].parent=i;
		(*HT)[s2].parent=i;
		(*HT)[i].left=s1;
		(*HT)[i].right=s2;
		(*HT)[i].value=(*HT)[s1].value+(*HT)[s2].value;
	}

}

void HuffmandCoding(HuffmandTree HT,HuffmandCode *HC,int n)
{
	*HC=(HuffmandCode)malloc((n+1)*sizeof(char *));
	char *cd=(char*)malloc(n*sizeof(char));//用于存放编码
	cd[n-1]='\0';
	for(int i=1;i<=n;i++)//从叶子节点出发,逆序
	{
		int start=n-1;//逆序存储
		int c=i;
		int j=HT[i].parent;
		while(j!=0)
		{
			if(HT[j].left==c)
			   cd[--start]='0';
			else
				cd[--start]='1';
			c=j;
			j=HT[j].parent;
		}
		(*HC)[i]=(char *)malloc((n-start)*sizeof(char));
		strcpy((*HC)[i],&cd[start]);
	}
	free(cd);
}
//void print(HuffmandCode htable,int *w,int n)
//{
//	for(int i=1;i<=n;i++)
//	{
//		cout<<htable[i];
//	}
//	cout<<endl;
//}
int main(){
	string str;
	cin>>str;
	int len=str.size();
	map<char,int> arr;
	for(int i=0;i<len;i++)
	{
		arr[str[i]]++;
	}
	len=arr.size();
	int *w=(int*)malloc(len*sizeof(int));//存放频率的数组
	i=0;
	for(map<char,int>::iterator it=arr.begin();it!=arr.end();it++)
	{
	    w[i]=it->second;
		// cout<<w[i];
		i++;
	}
	HuffmandTree htree;
	HuffmandCode htable;
    createHuffmand(&htree,w,len);
	HuffmandCoding(htree,&htable,len);
    map<char,char*> codes;
	it=arr.begin();
	for(i=1;i<=len;i++)
	{
        codes[it->first]=htable[i];
		it++;
	}
	for(i=0;i<str.size();i++)
	{
		cout<<codes[str[i]];
	}
	cout<<endl;

    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值