#include "stdio.h"
#include "stdlib.h"
#define N 10
int A[2*N];//标志数组,用于Select函数
typedef struct {
char value;
int weight;
int parent;
int lchild;
int rchild;
}HTNode;//HuffManTree结点
typedef struct HCNode{
char value;
struct HCNode *next;
}HCNode;//HC结点
int Select(HTNode *HT,int n,int *i,int *j){
int k=1;
for (k=1,*i=0; k<=n; k++){
if(HT[k].weight <= HT[*i].weight)
if(A[k] == 0)
*i=k;
if(k==n)
A[*i]=1;
}
for (k=1,*j=0; k<=n; k++){
if(HT[k].weight <= HT[*j].weight)
if(A[k] == 0)
*j=k;
if(k==n)
A[*j]=1;
}
return 1;
}
HuffManHC(HTNode * HT,HCNode * HC){
int i,p,q;
HCNode * HC1;
for (i=1; i<=N; i++){
p=i;
HC[i].value=HT[i].value;
while(HT[p].parent != 0){
q=p;
p=HT[p].parent;
HC1=(HCNode *)malloc(sizeof(HCNode));
if(HT[p].lchild == q)
HC1->value='0';
else HC1->value='1';
HC1->next=HC[i].next;
HC[i].next=HC1;
}
}
for (i=1; i<=N; i++){//输出HuffMan编码所对应的数组型链表
printf("%c: ",HC[i].value);
HC1=HC[i].next;
while(HC1){
printf("%c",HC1->value);
HC1=HC1->next;
}
printf("\n");
}
}
int main () {
char v;
int i,j,k;
HTNode *HT;
HCNode *HC;
int m=2*N-1;//总节点数目
HT = (HTNode *) malloc ((m+1) * sizeof(HTNode));//0号单元不用
for (i=0; i<m+1; i++) {
HT[i].value='^';
HT[i].weight=0;
HT[i].parent=0;
HT[i].lchild=0;
HT[i].rchild=0;
}//初始化HuffManTree
for (i=1; v !='!'; i++){//输入字符,并用求对应权值,注意此程序限制叶子节点个数位N,字符常量
v=getchar();
for (j=1; j<=i; j++){//判断字符是否与先前输入相同
if(v==HT[j].value && v!='!'){
HT[j].weight += 1;//相同则权值+1
i--;
break;
}
if(i==j && v!='!'){
HT[i].value=v;
HT[i].weight=1;
}
}
}
for (i=0;i<m+1;i++)
A[i]=0;//初始化标志数组
HT[0].weight=100000;//鉴于Select函数特殊需要,避免了部分错误
for(k=N+1; k<=m; k++){//建立完整HuffManTree
Select(HT,k-1,&i,&j);//通过函数选择权值最小的两个结点,/HT为指针/
HT[k].lchild=i;
HT[k].rchild=j;
HT[k].weight=HT[i].weight+HT[j].weight;
HT[i].parent=k;
HT[j].parent=k;
}
for (i=0; i<=m; i++)//输出数组表示法所建立的HuffManTree
printf("%c %4d%4d%4d%4d\n",HT[i].value,HT[i].weight,HT[i].parent,HT[i].lchild,HT[i].rchild);
HC=(HCNode *)malloc((N+1)*sizeof(HCNode));
for (i=0;i<=N;i++)//初始化HuffMan编码数组链表
HC[i].next=NULL;
HuffManHC(HT,HC);
getchar();
j=2*N-1;
v=' ';
for(; v!='!'; ){
v=getchar();
if(v=='0')
j=HT[j].lchild;
else if (v=='1')
j=HT[j].rchild;
else if(v!='!'){
printf("ENTER ERROR1\n");
exit(0);
}
}
if(j>N)
printf("ENTER ERROR2\n");
if(0 < j && <= N)
printf("%c\n",HT[j].value);
if(j==0)
printf("ENTER ERROR3\n");
return 0;
}