版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_39984761/article/details/78858495
首先构造哈夫曼树结构体,初始化哈夫曼树的四个无符号整型域,输入文本,统计各个字符的权值,然后构建哈夫曼树,从根到叶子逆向求哈夫曼树的编码。
#include"stdio.h"
#include"string.h"
#include"malloc.h"
#include"iostream"
using namespace std;
typedef struct{
unsigned int weight;
unsigned int parent,lchild,rchild;
}HTNode,*HuffTree;
typedef char **HuffCode;
void Select(HuffTree &Ht, int m, int &S1, int &S2)
{/*
Select函数,每次从前面数据中选择2个权值(weight值)最小的,将
最小的两个下标赋给s1,s2
*/
int j;
S1 = 0;
S2 = 0;
for (j = 1; j <= m; j++)
{
if (Ht[j].parent == 0 && Ht[j].weight != 0)
{
if (Ht[j].weight<Ht[S1].weight)
S1 = j;
}
}
for (j = 1; j <= m; j++)
{
if (Ht[j].parent == 0 && j != S1&&Ht[j].weight != 0)
{
if (Ht[j].weight<Ht[S2].weight)
S2 = j;
}
}
}
void HuffmanCoding(HuffTree &Ht,HuffCode &Hc,int n){ //哈夫曼编码函数
if(n<=1)return;
int m,i,s1, s2;
HuffTree p;
m =2*n-1;
Ht = (HuffTree)malloc((m + 1) * sizeof(HTNode));
char ch[100];
for (p = Ht + 1, i = 1; i <= m; ++i, ++p) { //初始化哈夫曼树各个值
p->weight = 0;
p->parent = 0;
p->lchild = 0;
p->rchild = 0;
}
cin >> ch; //读入一段文本
for (int i = 0; ch[i] !='\0'; i++) {
Ht[ch[i] - 'a'+1].weight++; //当文本还没有结束时,统计各个字符的权值
}
for(i=n+1;i<=m;++i){ //建哈夫曼树
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;
}
// 从叶子到根逆向求每个字符的哈夫曼编码
Hc=(HuffCode)malloc((n+1)*sizeof(char*));
char * cd=(char*)malloc((n)*sizeof(char));
int c,f;
cd[n-1]='\0'; //编码结束符
int start;
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';
}
//cd[n-1]='\0';
Hc[i]=(char *)malloc((n-start)*sizeof(char));
strcpy(Hc[i],&cd[start]);
}
free(cd);
}
void show(HuffCode &Hc, int n)//输出哈夫曼编码
{
int i, k;
cout<<" 输出哈夫曼编码:\n"; //输出哈夫曼编码
for (i = 1; i<=n; i++)
{
cout<< Hc[i];
cout<<"\n";
}
}
然后在主函数中调用,加入输入输出语句即可
#include"1.h"
using namespace std;
int main()
{
HuffTree ht;
HuffCode hc;
int n;
cout << "请输入文本";
HuffmanCoding(ht,hc,26);
show(hc,26);
system("pause");
}