#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
using namespace std;
typedef struct HTNode// 静态三叉链表
{
unsigned int weight;
unsigned int parent,lchild,rchild;
}HTNode,*HuffmanTree;//动态分配数组存储哈夫曼树
typedef char * *HuffmanCode;
int s1,s2,s3,s4;
int qz[20];//权值
int Select(HuffmanTree &HT,int n)
{
int i,j,k=0,min1,min2;
for(i=1;i<=n;i++)
{
if(HT[i].parent==0&&k==0)
{ k=i; min1=HT[i].weight;s3=i;}
if(HT[i].parent==0&&k!=i)
{ min2=HT[i].weight;s4=i;break;}
}
for(j=i;j<=n;j++)
{
if(HT[j].parent==0)
{
k=HT[j].weight;
if(k<min1)
{
min2=min1;
s4=s3;
min1=k;
s3=j;
}
else if(k<min2)
{min2=k;s4=j;}
}
}
s1=min1;
s2=min2;
return 1;
}
void HuffmanCoding(HuffmanTree &HT,int *w,int n)//HuffmanCode &HC
{
if(n<=1) return;
int m=2*n-1;int i;
HT=(HuffmanTree)malloc((m+1)*sizeof(HTNode));//0 号单元未用
HTNode *p;
for(p=HT+1,i=1;i<=n;++i,++p,++w)
{
(*p).weight=*w;
(*p).parent=0;
(*p).lchild=0;
(*p).rchild=0;
}
for(;i<=m;++i,++p)
{
(*p).weight=0;
(*p).parent=0;
(*p).lchild=0;
(*p).rchild=0;
}
for(i=n+1;i<=m;++i)//建立哈夫曼树
{ // 在HT[1...i-1]选择parent为0且weight最小的两个结点,s1,s2为其序号
Select(HT,i-1);
HT[s3].parent=i;
HT[s4].parent=i;
HT[i].lchild=s3;
HT[i].rchild=s4;
HT[i].weight=HT[s3].weight+HT[s4].weight;
}
//从叶子到根逆向求每个字符的哈弗曼编码
HuffmanCode HC;
HC=(HuffmanCode)malloc((n+1)*sizeof(char *));//分配n个字符编码的头指针向量
char *cd;
cd=(char *)malloc(n*sizeof(char));
cd[n-1]='\0';
int start,c,f;
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';
HC[i]=(char*)malloc((n-start)*sizeof(char));
strcpy(HC[i],&cd[start]);
}
free(cd);
for(i=1;i<=n;i++)
cout<<HC[i]<<endl;
}
int main()
{
HuffmanTree HT;
int i,n;
scanf("%d",&n);
for(i=0;i<n;i++)
cin>>qz[i];
//HT=(HuffmanTree)malloc((2*n)*sizeof(HTNode));//0 号单元未用
HuffmanCoding(HT,qz,n);
return 0;
}
/*
8
5 29 7 8 14 23 3 11
*/
哈弗曼编码
最新推荐文章于 2022-05-26 21:33:14 发布