接上文:
c++哈夫曼树+哈夫曼编码详解_浪子小院的博客-CSDN博客
前言
发了哈夫曼树的代码版,有粉丝催我要哈夫曼编码的代码了。
在这里,我就来展示一个吧。
题目:
有有一段要传送的字符串,长度不超过1M,问怎样设计Huffman编码?
输入格式
第一行一个由小写字母组成的字符串,长度范围[100,1000000]。
输出格式
每行对应一个编码。表示’a’到’z’的哈夫曼编码。答案不唯一,输出任意一种即可。
没有出现的字母不用编码。
输入/输出例子1
输入:
abxxaazbaxax
输出:
a=0
b=101
x=11
z=100
代码
哈夫曼编码是一种用来压缩数据的编码算法。它是由美国数学家大卫·哈夫曼在1952年发明的。哈夫曼编码通过对不同字符赋予不同的编码来压缩数据,使得数据在传输或存储时所占用的空间更小,从而提高了数据传输和存储的效率。
哈夫曼编码的基本思想是:对于出现频率较高的字符,赋予较短的编码,而对于出现频率较低的字符,赋予较长的编码。这是因为出现频率较高的字符被赋予较短的编码后,它们在数据中所占用的位数就会减少,从而使得数据压缩的效果更好。
#include<bits/stdc++.h>
using namespace std;
class huffmancode{
public:
string Huffmancode[1000];
struct Tnode{
int father,left,right,weight;
Tnode()
{
father=left=right=weight=0;
}
Tnode(int Father,int Left,int Right,int Weight)
{
father=Father;
left=Left;
right=Right;
weight=Weight;
}
}Tree[100005];
int findmax1(int m)
{
int Max=INT_MAX,id=1;
for(int j=1;j<=m;j++)
{
if(Tree[j].weight>0 && Tree[j].father==0 && Tree[j].weight<Max)
{
Max=Tree[j].weight;
id=j;
}
}
return id;
}
void findmax2(int m,int &a,int &b)
{
a=findmax1(m);
Tree[a].father=-1;
b=findmax1(m);
}
void depth(int root,string code)
{
if(Tree[root].left==0)
{
Huffmancode[root]=code;
return ;
}
depth(Tree[root].left,code+"0");
depth(Tree[root].right,code+"1");
}
};
int main()
{
string s;
int n,m;
n=m=0;
huffmancode h;
cin>>s;
for(int i=0;i<s.size();i++)
{
h.Tree[s[i]-96].weight++;
}
for(int i=1;i<=26;i++)
{
if(h.Tree[i].weight>0)
n++;
}
m=26;
for(int i=1;i<n;i++)
{
int max1,max2;
h.findmax2(m,max1,max2);
++m;
h.Tree[m].father=0;
h.Tree[m].left=max1;
h.Tree[m].right=max2;
h.Tree[m].weight=(h.Tree[max1].weight+h.Tree[max2].weight);
h.Tree[max1].father=h.Tree[max2].father=m;
}
h.depth(h.findmax1(m),"");
for(int i=1;i<=26;i++)
{
if(h.Tree[i].weight>0)
{
cout<<char(i+'a'-1)<<"="<<h.Huffmancode[i]<<endl;
}
}
return 0;
}