#include<iostream>
#include<math.h>
#include<string.h>
using namespace std;
#define MAXSIZE 100
//叶子结点定义:
typedef struct{
double weight;//权
int parent,lc,rc;
}TNode,*HFMTree;
typedef char** HFMCode;//存储哈夫曼编码,2级指针
//选出2个最小的权值
void Select(HFMTree T,int k,int &s1,int &s2){
double min = MAXSIZE;
for(int i=1;i<=k;i++){//最小
if(T[i].parent==0 && T[i].weight<min){
min = T[i].weight;
s1 = i;
}
}
min = MAXSIZE;
for(int i=1;i<=k;i++){//次最小
if(i!=s1 && T[i].parent==0 && T[i].weight<min){
min = T[i].weight;
s2 = i;
}
}
}
//编码,创造哈夫曼树
void HFMCoding(HFMTree &T,HFMCode &C,double w[],int n){//w为1维数组,存放n个字符的权
if(n<=1)
return;
//哈夫曼树没有度为1的结点,所以有n个叶子节点的哈夫曼树有2n-1个结点
int m = 2*n-1;
int i,s1,s2;
HFMTree p = NULL;
T = new TNode[m+1];//0号单元不
for(p=T+1,i=1 ; i<=n ; ++i,++p,++w){ //先把叶子结点们初始化,并且附上权值,i从1开始
p->weight = *w;
p->lc = 0;
p->rc = 0;
p->parent = 0;
}
for( ; i<=m ; ++i,++p){ //再把新增的结点初始化,权值默认先为0
p->weight = 0;
p->lc = 0;
p->rc = 0;
p->parent = 0;
}
for(i=n+1;i<=m;++i){
Select(T,i-1,s1,s2);
//认亲:
T[s1].parent = i;
T[s2].parent = i;
//认子:
T[i].lc = s1;
T[i].rc = s2;
//孝敬:
T[i].weight = T[s1].weight+T[s2].weight;
}
//从叶子节点到根逆向求每个字符的 HFMCODE
C = new char*[n+1];
//分配n个字符编码的头指针
char *cd = new char[n];
cd[n-1] = '\0';
for(i=1;i<=n;i++){
int start=n-1;
for(int c=i,f=T[i].parent ; f!=0 ; c=f,f=T[f].parent)
if(T[f].lc==c)
cd[--start] = '0';
else
cd[--start] = '1';
//为di个字符编码分配空间
//###########################################
//i-1是因为s是从0开始是d1元素,主函数为了和s一起从0输出,不然会C的首元素为空,C无法访问
//##########################################
C[i-1] = new char[n-start];
strcpy(C[i-1],&cd[start]);
}
delete cd;
}
int main(){
int n;
cin>>n;
char s[20];
cin>>s;
double w[20];
for(int i=0;i<n;i++)
cin>>w[i];
HFMCode C;
HFMTree T;
HFMCoding(T,C,w,n);
for(int i=0;i<n;i++){
cout<<"The "<<s[i]<<" 's Huffman code is:"<<C[i]<<endl;
}
}
哈夫曼树
最新推荐文章于 2023-05-24 23:42:43 发布