////////////////////////////////////////////////////////////////////////////////////
#include<stdio.h>
#include<string.h>
#define MAX 3
typedef struct //////////////////////定义哈夫曼的类型
{
int weight; //////////////////////权值
char data; //////////////////////输入字符
int parent,lchild,rchild; /////////////////////树的下标
}hufmtree;
////////////////////////////////////////////////////
typedef struct
{
char ch; ////////////////////字符集的大小为n,则变长编码的长度不会超过n,加上一个结束字符'\0',因此bits的大小可设为n+1
char bits[MAX+1];
}huffmancode;
//////////////////////////////////////////////////////
void select(hufmtree tree[],int n,int &p1,int &p2)
{
int i;
p1=p2=1;
while(tree[p1].parent!=0) //领p1指向未被使用的结点
{p1++;}
for(i=2;i<=n;i++) //找出第一个最小权值的值p1
{
if(tree[i].weight<tree[p1].weight && tree[i].parent==0)
p1=i;
}
tree[p1].parent=1; //
while(tree[p2].parent!=0) //领p2指向未被使用的结点
{p2++;} //初始p2=p2=1; 当p1=1为最小的时候 p2也只会是1所以要令p2=2开始
for(i=2;i<=n;i++)
{
if(tree[i].weight<tree[p2].weight && tree[i].parent==0)
p2=i;
}
tree[p2].parent=1;
}
/////////////////////////////////////////////////////
void creathuffman(hufmtree tree[],int n)
{
int m,i,p1,p2,f;
char c;
if(n<=1)
return;
m=2*n;
for(i=1;i<m;i++) //
{
tree[i].parent=0; ///////////////////////////////对数组初始化,下标为0的单元不用
tree[i].lchild=0; //
tree[i].rchild=0;
tree[i].weight=0;
}
printf("请输入权值和字符\n");
for(i=1;i<=n;i++)
{
scanf("%d,%c",&f,&c);
tree[i].weight=f;
tree[i].data=c;
}
for(i=n+1;i<m;i++)
{
select(tree,i-1,p1,p2); ////////////////////////////////进行合并,产生n-1个节点
tree[p1].parent=i;
tree[p2].parent=i;
tree[i].lchild=p1;
tree[i].rchild=p2;
tree[i].weight=tree[p1].weight+tree[p2].weight;
}
}
////////////////////////////////////////////////////////////
void print(hufmtree tree[],int n)
{
int i;
printf("data weight parent lchild rchild\n");
for(i=1;i<=n;i++)
{
printf("%3c %3d %3d %3d %3d\n",tree[i].data,tree[i].weight,tree[i].parent,tree[i].lchild,tree[i].rchild);
}
}
///////////////////////////////////////////////////////////////
void huffmancoding(hufmtree tree[],huffmancode h[])
{
int start,c,p,i;
char cd[MAX+1]; ////存放编码的临时变量
cd[MAX]='\0';
for(i=1;i<=MAX;i++)
{
h[i].ch=tree[i].data;
start=MAX;
c=i;
while(p=tree[c].parent) // 关键
{
if(tree[p].lchild==c) //
cd[--start]='0'; //
else //
cd[--start]='1'; //
c=p; //
} // 关键
strcpy(h[i].bits,&cd[start]);
puts(h[i].bits);
printf("\n");
}
}
////////////////////////////////////////////////////////////////////////////////
void yima(hufmtree tree[], int n ) //////////
{
int i,p;
char a[50];
p=2*n-1; ///////注意
printf("请输入编码,就可翻译出字符");
scanf("%s",a);
for(i=0;i<=strlen(a);i++)
{
if(tree[p].lchild!=0 && tree[p].rchild!=0)
{
if(a[i]=='0')
{p=tree[p].lchild;} //////////
else
{p=tree[p].rchild;} //////////
}
if(tree[p].lchild==0)
{
printf("%c ",tree[p].data);
p=2*n-1;
}
}
printf("\n");
}
/////////////////////////////////////////////////////////////////////////////////
int main()
{
int i=0,f,n;
char ch;
hufmtree tree[100]; /////////////这是一个数组
huffmancode h[MAX]; ////////////
printf("请输入节点数\n");
scanf("%d",&n);
creathuffman(tree,n);
print(tree,n);
huffmancoding(tree,h);
yima(tree,n);
return 0;
}
////////////////////////////////////////////////////////////////