原题 : http://acm.nyist.net/JudgeOnline/problem.php?pid=801
HuffmanTree 建立与编码: http://blog.youkuaiyun.com/zark721/article/details/76516189
//nyoj 801
//构建huffman树的过程稍做修改即可
//每一次动态申请内存malloc,要手动释放free,防止内存泄漏,还可以提高速度。
//因为 malloc是从堆区申请空间,函数结束后不会自动释放,如果不人为地释放的话,要等到程序结束后,系统才会自动回收,累积到一定程度,程序会崩溃(摘自百度)
#include<iostream>
#include<cstdio>
#include<stdlib.h>
using namespace std;
struct input
{
char ch;
int w;
}in[101];
typedef struct Node
{
char ch;
int weight;
int lchild;
int rchild;
int parent;
}HTNode,*HuffmanTree;//存放树的所有节点
typedef char**HuffmanCode ;//存放每一个叶子结点的编码
void strcpy(char *to,char * from)
{
int i=0;
while(from[i]!='\0')
{
to[i]=from[i];
i++;
}
to[i]='\0';
}
void findmin(HuffmanTree ht,int k,int &min1,int &min2);
int min(HuffmanTree ht,int k);
HuffmanTree HuffmanTreeBuild(int n)//建树函数
{
int i;
int total=2*n-1;//树的节点总数
HuffmanTree ht=(HTNode *) malloc(total*sizeof(HTNode));
//初始化
for(i=0;i<n;i++)
{
ht[i].lchild=-1;
ht[i].rchild=-1;
ht[i].parent=-1;
ht[i].ch=in[i].ch;
ht[i].weight=in[i].w;
}
for(;i<total;i++)
{
ht[i].lchild=-1;
ht[i].rchild=-1;
ht[i].parent=-1;
ht[i].weight=0;
}
int min1,min2;//权值最小的两棵二叉树
for(i=n;i<total;i++)
{
findmin(ht,i,min1,min2);
ht[i].lchild=min1;
ht[i].rchild=min2;
ht[min1].parent=ht[min2].parent=i;
ht[i].ch=ht[ht[i].lchild].ch;
ht[i].weight=ht[min1].weight+ht[min2].weight;
}
return ht;
}
void findmin(HuffmanTree ht,int k,int &min1,int &min2)
{
min1=min(ht,k);
min2=min(ht,k);
}
int min(HuffmanTree ht,int k)
{
int i=0;
int min;
int minw;
char ch;
while(ht[i].parent!=-1)
{
i++;
}
min=i;
minw=ht[i].weight;
ch=ht[i].ch;
i++;
while(i<k)
{
if(ht[i].parent==-1 && ht[i].weight<=minw)
{
if(ht[i].weight<minw || (ht[i].weight==minw && ht[i].ch<ch))
{
min=i;
minw=ht[i].weight;
ch=ht[i].ch;
}
}
i++;
}
ht[min].parent=1;
return min;
}
HuffmanCode HuffmanTreeCoding(HuffmanTree ht,int n)
{
HuffmanCode hc=(HuffmanCode)malloc(n*sizeof(char *));
int i;
char *tmp=(char *)malloc(n*sizeof(char));
tmp[n-1]='\0';
for(i=0;i<n;i++)
{
int start=n-1;
int cur=i;
int parent=ht[i].parent;
while(parent!=-1)
{
if(ht[parent].lchild==cur){
tmp[--start]='0';
}else{
tmp[--start]='1';
}
cur=parent;
parent=ht[parent].parent;
}
int len=n-start;
hc[i]=(char *)malloc(len*sizeof(char));
strcpy(hc[i],tmp+start);
}
return hc;
}
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
getchar();
for(int i=0;i<n;i++)
{
scanf("%c %d",&in[i].ch,&in[i].w);
getchar();
}
HuffmanTree ht=HuffmanTreeBuild(n);
HuffmanCode hc=HuffmanTreeCoding(ht,n);
for(int i=0;i<n;i++)
{
printf("%c:%s\n",in[i].ch,hc[i]);
}
free(ht); //释放内存速度快了3倍。
free(hc);
}
return 0;
}