#include<stdio.h>
#include<string.h>
#define OK 1
#define ERROR 0
#define OVERFLOW -2
#define MAXSIZE 100
typedef int Status;
int num[256]={0},H[256]={0};
//哈夫曼树的存储表示
typedef struct
{
int weight; //结点权值
int perent,lchild,rchild; //结点的双亲,左孩子,右孩子的下标
} HTNode,*HuffmanTree; //动态分配数组存储哈夫曼树
//构造哈夫曼树中的Select函数
void Select(HuffmanTree HT,int n,int &s1,int &s2) //s1,s2要取地址
{
float min1=99999,min2=99999;
int i;
for(i=1;i<=n;i++)
if(min1>HT[i].weight&&HT[i].perent==0)
{min1=HT[i].weight;s1=i;}
for(i=1;i<=n;i++)
if(min2>HT[i].weight&&HT[i].perent==0&&HT[i].weight!=min1)
{min2=HT[i].weight;s2=i;}
}
//构造哈夫曼树
void CreateHuffmanTree(HuffmanTree &HT,int n)
{ int i,m,s1,s2; //初始化
if(n<=1) return;
m=2*n-1;
HT=new HTNode[m+1];
for(i=1;i<=m;++i)
{
HT[i].perent=0;
HT[i].lchild=0;
HT[i].rchild=0;
}
for(i=1;i<=n;++i)
// scanf("%d",HT[i].weight);
HT[i].weight=H[i];
//开始构造哈夫曼树
for(i=n+1;i<=m;++i)
{
Select(HT,i-1,s1,s2);
HT[s1].perent=i;
HT[s2].perent=i;
HT[i].lchild=s1;
HT[i].rchild=s2;
HT[i].weight=HT[s1].weight+HT[s2].weight;
}
}
//哈夫曼编码表的存储表示
typedef char **HuffmanCode; //动态分配数组存储哈夫曼编码表
//根据哈夫曼树求哈夫曼编码,存储在编码表HC中
void CreateHuffmanCode(HuffmanTree HT,HuffmanCode &HC,int n)
{
int c,f,start,i;char *cd;
HC=new char*[n+1]; //分配存储n个字符编码的编码表空间
cd=new char[n]; //分配临时存放每个字符编码的动态数组空间
cd[n-1]='\0'; //编码结束符
for(i=1;i<=n;++i) //逐个字符求哈夫曼编码
{
start=n-1;
c=i;f=HT[i].perent;
while(f!=0)
{
--start;
if(HT[f].lchild==c) cd[start]='0';
else cd[start]='1';
c=f;f=HT[f].perent;
}
HC[i]=new char[n-start];
strcpy(HC[i],&cd[start]);
}
//delete cd;
for(i=1;i<=n;i++)
printf("%s ",HC[i]);
}
//打印哈夫曼树
int main()
{ // (1)统计字符串各字符的频率
char str;
char str[20];
int i,num[256]={0};
printf("please input string:");
scanf("%s",str);
for(i=0;i<strlen(str);i++)
{
num[(int)str[i]]++;
}
for(i=0;i<256;i++)
{
if(num[i]!=0)
{
printf("字符%c出现%d次\n",(char)i,num[i]);
}
}
//(1)统计字符串各字符的频率
HuffmanCode HC;
HuffmanTree HT;
CreateHuffmanTree(HT,j);
CreateHuffmanCode(HT,HC,j);
return 0;
}