#include
#include
#include
#include
#include
#define MAXV 100
//#define MAXVALUE 10000
typedef struct
{
char data; //结点的值
int weight; //权值
int parent,lchild,rchild; //父节点,左孩子结点,右孩子结点
}HTNode,* HuffmanTree; //动态分配数组存哈夫曼树
typedef char **HuffmanCode;
void init(HuffmanTree &HT,int n)
{ //初始化建立哈弗曼树
int i;
char num=0;
HT=(HuffmanTree)malloc((2*n)*sizeof(HTNode));//0号单元未用··从1开始
for(i=1;i<2*n;i++)
{
HT[i].data=num;
HT[i].parent=0;
HT[i].weight=0;
HT[i].lchild=0;
HT[i].rchild=0;
}
for(i=1;i
getchar();
printf("输入第%d个结点的值:",i);
scanf("%c",&HT[i].data);
printf("对应权值:");
scanf("%d",&HT[i].weight);
}
printf("初始建立成功!");
printf("\n");
printf("\n***********初始情况如下***********\n");
printf("字符值 权值 双亲 左孩子 右孩子\n");
for(i=1;i<=2*n-1;i++)
{
printf("%3c %d %3d %5d %5d\n",HT[i].data,HT[i].weight,HT[i].parent,HT[i].lchild,HT[i].rchild);
}
printf("*********************************\n");
}
void Select(HuffmanTree &HT,int m,int *s1,int *s2)//找到频率最低的两个结点
{
int i,min1,min2;
HT[min1].weight=MAXV;
HT[min2].weight=MAXV;
for(i=1;i<=m;i++)
{
if(HT[i].parent==0)
{
if(HT[i].weight
}
}
*s1=min1;
for(i=1;i<=m;i++)
{
if(HT[i].parent==0&&i!=(*s1))
{
if(HT[i].weight
}
}
*s2=min2;
}
//构造哈弗曼树 借用书上代码[数据结构C语言版(严蔚敏 吴伟民)]
void HuffmanCoding(HuffmanTree &HT,HuffmanCode &HC,int n)
{
int i,s1,s2;
int c,f;
int start;
char *cd;
printf("\n***************哈弗曼树****************\n");
for(i=n+1;i<=2*n-1;++i) // 建赫夫曼树
{
Select(HT,i-1,&s1,&s2);
HT[s1].parent=HT[s2].parent=i;
HT[i].lchild=s1;
HT[i].rchild=s2;
HT[i].weight=HT[s1].weight+HT[s2].weight;
}
printf("字符值 权值 双亲 左孩子 右孩子\n");
for(i=1;i<=2*n-1;i++)
{
printf("%3c %2d %3d %5d %5d\n",HT[i].data,HT[i].weight,HT[i].parent,HT[i].lchild,HT[i].rchild);
}
printf("*******************************************\n");
printf("\n");
printf("%d个字符的哈弗曼编码如下:\n",n);
HC=(HuffmanCode)malloc((n+1)*sizeof(char*));
cd=(char*)malloc(n*sizeof(char));
cd[n-1]='\0';
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]); //strcpy是字符串复制函数
}
free(cd);
for(i=1;i<=n;i++)
printf("'%c'编码:%s\n",HT[i].data,HC[i]);
}
//哈弗曼树编码 从已经构造的树中取出编码···
void translateHuffmancode(HuffmanTree &HT,HuffmanCode &HC,int n)
{
char str[MAXV],result[MAXV]="\0";
char temp;
int i,j;
getchar();
printf("\n请输入要编码的字符:");
gets(str);
for(i=0;str[i]!='\0';i++)
{
temp=str[i];
for(j=1;j<=n;j++)
if(str[i]==HT[j].data)
strcat(result,HC[j]); //strcat是字符串连接函数
}
printf("所求哈夫曼编码为:");
puts(result);
}
//菜单函数
char menu()
{
char n;
// system("CLS"); /*清屏函数 其头文件为“#include
system("color 0A"); /*屏幕和字体颜色控制*/
printf("欢迎进入系统:\n");
printf("\t\t\t 哈夫曼编码 \n");
printf("\t******************************菜单*****************************\n");
printf("\t***************************************************************\n");
printf("\t|*********** ***********|\n");
printf("\t|******* ******|\n");
printf("\t|**** 1.构造哈弗曼树 2.哈弗曼编码 ****|\n");
printf("\t|**** ****|\n");
printf("\t|**** 3.退出系统 ****|\n");
printf("\t|**** ****|\n");
printf("\t|******* 注:(必须先构建哈弗曼树)******|\n");
printf("\t***************************************************************\n");
printf("\t***************************************************************\n");
printf("选择1-3:[ ]\b\b");
while(1)
{
n=getchar();
if(n<'1'||n>'3')printf("输入错误,请重新输入1-3:[ ]\b\b");
else
break;
}return n;
}
//从键盘输入结点个数
int dedao()
{ int n;
printf("初始建立输入结点个数(必须输入数字):");
scanf("%d",&n);
return n;
}
void main()
{ system("color 0A"); //屏幕和字体颜色控制
int n;
HuffmanTree HT; //代表赫夫曼树
HuffmanCode HC; //代表赫夫曼编码
while(1)
switch(menu())
{ case '1':n=dedao();
init(HT,n); HuffmanCoding(HT,HC,n); break;
case '2': translateHuffmancode(HT,HC,n); break;
case '3':printf("谢谢使用,再见!!!\n\n");exit(0);break;
}
}