#include<bits/stdc++.h> //因为要用到几个头文件,比较麻烦,可以直接用万能头文件
using namespace std;
#define maxvalue 32376
typedef struct
{
int weight;
int parent,lchild,rchild;
} HTNode,*HuffmanTree;
typedef char **HuffmanCode;
int Select(HuffmanTree HT,int n,int &s1,int &s2) //选出权值最小的两个结点去构造哈夫曼
树
{
int i,min1=maxvalue,min2=maxvalue;
for(int i=1;i<=n;i++)
if((HT[i].weight<min1)&&(HT[i].parent==0))
{
min1=HT[i].weight;
s1=i;
}
for(int i=1;i<=n;i++)
if((HT[i].weight<min2)&&(HT[i].parent==0))
if(i!=s1)
{
min2=HT[i].weight;
s2=i;
}
}
int CreateHuffmanTree(HuffmanTree &HT,int n) //构造哈夫曼树
{
int i,m,s1,s2;
m=2*n-1; //关于如何构造哈夫曼树博主的上篇文章里有详
//解
HT=new HTNode[m+1];
for(i=1;i<=m;i++)
{
HT[i].parent=0;HT[i].lchild=0;HT[i].rchild=0;
}
cout<<"请输入各结点的权值:";
for(i=1;i<=n;i++)
cin>>HT[i].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;
}
}
int CreateHuffmanCode(HuffmanTree HT,HuffmanCode &HC,int n)
{
int i,start,c,f;
HC=new char*[n+1]; //为存储哈夫曼编码的数组开辟空间
char *cd=new char[n]; //构造一个临时存储哈夫曼编码的数组
cd[n-1]='\0'; //哈夫曼编码是倒叙存入cd数组中的
for(i=1;i<=n;i++)
{
start=n-1; // cd数组从0开始,所以n-1是最后一个空间
c=i;f=HT[i].parent;
while(f!=0) //从第i个叶子结点一直回溯到跟结点
{
--start;
if(HT[f].lchild==c) cd[start]='0'; //左0右1
else
cd[start]='1';
c=f;f=HT[f].parent;
}
HC[i]=new char[n-start]; //为节省空间,每个叶子结点的编码要占多少空间就在这分配多少
//空间
strcpy(HC[i],&cd[start]); //&cd[start]代表start为首地址,从cd首地址开始复制给HC;
}
delete cd; //释放临时数组cd
}
int show(HuffmanTree HT,HuffmanCode HC) //输出哈夫曼编码
{
for(int i=1;i<=sizeof(HC);i++)
cout<<HT[i].weight<<"的哈夫曼编码为:"<<HC[i]<<endl;
}
int main()
{
HuffmanTree HT;
HuffmanCode HC;
int n,i;
cout<<"请输入结点数:";
cin>>n;
cout<<endl;
CreateHuffmanTree(HT,n);
CreateHuffmanCode(HT,HC,n);
show(HT,HC);
return 0;
}
/*
8
5 29 7 8 14 23 3 11
*/
哈夫曼编码路径图
HC示意图
如果觉得对你有帮助,可以关注博主,了解更多数据结构知识,数据结构全篇知识点更新中......