Description
由键盘输入一组整数,作为权值序列,求赫夫曼编码并输出。
Input
输入为两行数据,第一行是一个整数,作为输入权值的个数(<=10),第二行为权值序列。
Output
输出为权值序列对应的赫夫曼编码,每个编码输出一行
Sample Input
4
4 3 2 1
Sample Output
4:0
3:10
2:110
1:111
#include<bits/stdc++.h>
using namespace std;
#define MIN 0x7fffffff
int arr[10000];
int n;
typedef struct {
unsigned int weight;//权重
unsigned int parent,lchild,rchild;//父亲节点,左孩子节点,右孩子节点
}HTNode,*HuffmanTree;
typedef char* *HuffmanCode;
void Select(HuffmanTree &HT,int n,int &min1,int &min2){//选择最小的且父亲节点为0的2个节点
unsigned int mini=MIN;
for(int i=1;i<=n;i++){
if(HT[i].parent==0){
if(HT[i].weight<mini){//找最小权重的节点
min1=i;
mini=HT[i].weight;
}
}
}
mini=MIN;
for(int i=1;i<=n;i++){
if(i==min1) continue;
if(HT[i].parent==0){//找第2个权重最小的节点
if(HT[i].weight<mini){
min2=i;
mini=HT[i].weight;
}
}
}
if((min2<min1)){//大小排序
int temp;
temp = min1;
min1 = min2;
min2 = temp;
}
}
void HuffmanCoding(HuffmanTree &HT,HuffmanCode &HC,int n){//哈夫曼树的创建与编码
if(n <= 1) return;//节点个数为1或0直接返回
int m;
m=2*n-1;//树的总的节点
HT = (HuffmanTree)malloc((m+1)*sizeof(HTNode));//创建一棵HT树
int i;
for(i=1;i<=n;i++){//先初始化n个节点
HT[i].weight = arr[i-1];
HT[i].parent = 0;
HT[i].lchild = 0;
HT[i].rchild = 0;
}
for(;i<=m;i++){//初始化剩下的节点
HT[i].weight = 0;
HT[i].parent = 0;
HT[i].lchild = 0;
HT[i].rchild = 0;
}
for(int i=n+1;i<=m;i++){
int s1,s2;
Select(HT,i-1,s1,s2);
HT[s1].parent = i;
HT[s2].parent = i;
HT[i].weight = HT[s1].weight+HT[s2].weight;
HT[i].lchild = s1;
HT[i].rchild = s2;
}
HC = (HuffmanCode)malloc((n+1) * sizeof(char *));//开始树的编码
char *ch;
ch = (char *)malloc(n * sizeof(char));
ch[n-1]='\0';
for(int i=1;i<=n;++i){
int k=n-1;
for(int j=i,f=HT[i].parent;f!=0;j=f,f=HT[f].parent){//编码
if(HT[f].lchild==j)
ch[--k]='0';//左为0
else
ch[--k]='1';//右为1
}
HC[i] = (char *)malloc((n-k) * sizeof(char));
strcpy(HC[i],&ch[k]);
}
free(ch);//回收
}
int main()
{
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%d",&arr[i]);
}
HuffmanTree HT;
HuffmanCode HC;
HuffmanCoding(HT,HC,n);
for(int i=1;i<=n;i++){
printf("%d:%s\n",arr[i-1],HC[i]);
}
}