#include<iostream>
#include<cstring>
#define ERROR 0
#define OK 1
using namespace std;
typedef struct{
int weight;
int parent,lch,rch;
}HTNode,*HuffmanTree;
typedef char** HuffmanCode; //数组中每个元素都是指针类型
//找1-n-1个结点中权重最小的两个结点
void Select(HuffmanTree HT,int n,int &s1,int &s2){
int i,j,min1,min2;
//找s1
for(i=1;i<=n;i++){
if(HT[i].parent==0){ //初始化min1:前n-1个结点中第一个双亲为0的结点
min1=i;
break;
}
}
for(j=min1+1;j<=n;j++){
if(HT[j].parent==0) //再找到一个双亲为0的结点
if(HT[j].weight<HT[min1].weight) min1=j; //将其权重与min1相比
}
s1=min1; //循环结束后,权重最小的结点下标为s1
//找s2
for(i=1;i<=n;i++){
if(HT[i].parent==0&&i!=s1){ //初始化min2:前n-1个结点中第一个双亲为0,且下标不为s1的结点
min2=i;
break;
}
}
for(j=min2+1;j<=n;j++){
if(HT[j].parent==0&&j!=s1) //跳过s1,找最小的结点
if(HT[j].weight<HT[min2].weight) min2=j;
}
s2=min2;
}
//构造哈夫曼树
int CreateHuffmanTree(HuffmanTree &HT,int n){
int m;
int s1,s2;
if(n<=1) return(ERROR);
m=2*n-1;
HT=new HTNode[m+1]; //数组长为2n
for(int i=1;i<=m;++i){ //将2n-1个元素的parent、lch、rch置0
HT[i].parent=0;
HT[i].lch=0;
HT[i].rch=0;
}
for(int i=1;i<=n;++i){ //输入前n个元素的weight
cin>>HT[i].weight;
}
for(int i=n+1;i<=m;i++){
Select(HT,i-1,s1,s2); //选最小结点s1,s2
HT[s1].parent=i; HT[s2].parent=i; //修改s1、s2结点的parent
HT[i].lch=s1;HT[i].rch=s2; //修改i结点的左右孩子
HT[i].weight=HT[s1].weight+HT[s2].weight; //修改i结点的权重
}
return OK;
}
//哈夫曼编码
void CreateHuffmanCode(HuffmanTree HT,HuffmanCode &HC,int n){
HC=new char*[n+1]; //分配n个字符编码的头指针矢量,下标从0-n(0不用,实际用1-n)
char *cd; //临时存放编码的数组cd,下标从0-n-1
cd=new char[n];
cd[n-1]='\0'; //结束符
for(int i=1;i<=n;i++){ //依次为n个字符编码
int start=n-1; //临时数组cd中的下标
int c=i; //当前结点
int f=HT[i].parent; //双亲
while(f!=0){ //从叶子结点向上回溯,到根结点为止(f==0)
--start; //每回溯一次,start向前一个位置
if(HT[f].lch==c) cd[start]='0'; //如果c是f的左孩子,记为0
else cd[start]='1'; //如果c是f的右孩子,记为1
c=f;f=HT[f].parent; //回溯
}
HC[i]=new char[n-start]; //分配HC[i]空间
strcpy(HC[i],&cd[start]); //将字符串首地址从临时数组cd复制到HC中
}
delete cd; //释放临时空间
}
int main(){
HuffmanTree HT;
HuffmanCode HC;
int n;
cout<<"输入结点数:";
cin>>n;
cout<<"请输入权重:";
CreateHuffmanTree(HT,n);
cout<<"各结点权重依次为:"<<endl;
for(int i=1;i<2*n;i++) cout<<HT[i].weight<<' ';
cout<<endl<<"构造成功"<<endl;
CreateHuffmanCode(HT,HC,n);
cout<<"哈夫曼编码HC:"<<endl;
for(int i=1;i<=n;i++) cout<<HC[i]<<' ';
return 1;
}
运行结果: