#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MaxSize 50
#define MAX 32767
/* int 8位整数*/
typedef struct{
char c; /* 字符; */
int w; /* 字符权值; */
char *code; /*字符的Huffman编码; */
}HuffmanCode[MaxSize];
typedef struct{
int weight; /* 权值; */
int lchild,rchild,parent;
}HTNode,HuffmanTree[MaxSize];
/* ================================================================================ */
void CreateHuffmanTree(HuffmanTree HT,int length,HuffmanCode hc); /* 生成Huffman树; */
void SelectHTNode(HuffmanTree HT,int n,int *min1,int *min2); /* 查找最小和次小序号; */
void HuffmanCoding1(HuffmanTree HT,int n,HuffmanCode hc); /* 生成Huffman编码; */
/* ================================================================================ */
int main()
{
HuffmanTree HT; /* Huffman树; */
HuffmanCode HC; /* Huffman编码; */
int i,n;
printf("--------HuffmanCode--------\n");
printf("\nPlease input the number of char:");
scanf("%d",&n);
system("cls");
printf("the number of char: %2d\n\n",n);
printf("Input the char and its weight: (e.g.: \"a16[enter]\" ): \n");
for(i=1;i <= n;i++)
{
while(getchar() != '\n') NULL;
printf("No.%2d: ",i);
HC[i].c = getchar();
scanf("%d",&HC[i].w);
}
CreateHuffmanTree(HT,n,HC);
HuffmanCoding1(HT,n,HC);
printf("\nOutput the Huffman Code:\n");
for(i = 1;i<=n;i++)
{
printf("\n %c :",HC[i].c);
puts(HC[i].code);
}
/* 测试Huffman树结构; */
printf("\n\nOutput the structure of Huaffman tree:");system("pause");
printf("\nHT[i]:\tweight\tparent\tLchild\tRchild\n");
for(i = 1;i<2*n;i++)
{
if(i <= n) printf("(%c)",HC[i].c);
printf("%2d:\t %2d;\t%2d,\t %2d,\t %2d.\n", i,HT[i].weight,HT[i].parent,HT[i].lchild,HT[i].rchild);
}
getch();
return 0;
}
/* ================================================================================ */
void CreateHuffmanTree(HuffmanTree HT,int length,HuffmanCode HC) /* Huffman树初始化; */
{
int i;
int min1,min2;//最小的两个权值
HT[0].weight = MAX;//哈夫曼树丛0开始储存权值
/*先把叶子节点的双亲,左右变量全部赋值为0*/
for(i = 1;i <= length;i++)
{
HT[i].weight = HC[i].w;//哈夫曼编码里的权值,赋值给哈夫曼树里面的权值
HT[i].lchild = HT[i].rchild = HT[i].parent = 0;//双亲,左右子树全部赋值为0
}
/*整个树的节点数是2*length-1,刨去第0个,就是2*length
上面一个循环已经把叶子的权值存放
剩下的节点就是树里面非叶子节点,里面不存放权值,
初始化的时候,这里先把左右、双亲变量赋值为0*/
for(;i < 2*length;i++) /* i初值 = length+1; */
{
HT[i].lchild = HT[i].rchild = HT[i].parent = 0;
}
for(i = length+1;i < 2*length;i++)
{
SelectHTNode(HT,i,&min1,&min2);
HT[min1].parent = i;
HT[min2].parent = i;
HT[i].lchild = min1;
HT[i].rchild = min2;
HT[i].weight = HT[min1].weight + HT[min2].weight;
}
}
/*==========================================================================*/
void SelectHTNode(HuffmanTree HT,int n,int *min1,int *min2) /* 查找最小和次小序号; */
{
int i;
*min1 = *min2 = 0;
for(i = 1;i < n;i++)
{
if(HT[i].parent == 0)
{
/* printf("\n i=%d,*min1=%d, HT[*min1].weight=%d",i,*min1,HT[*min1].weight);
printf("\n i=%d,*min2=%d, HT[*min2].weight=%d",i,*min2,HT[*min2].weight); */
if(HT[*min1].weight >= HT[i].weight)
{
*min2 = *min1;
*min1 = i;
/*printf("\n i=%d: *min1=%d, *min2=%d ",i,*min1,*min2); */
}
else
if(HT[*min2].weight > HT[i].weight)
{
*min2 = i;
/* printf("\n i=%d: *min1=%d, *min2=%d ",i,*min1,*min2); */
}
}
}
}
/* 生成Huffman编码=============================================================== */
void HuffmanCoding1(HuffmanTree HT,int n,HuffmanCode HC)
{
int i,start,c,f;
char *cd;
cd=(char * )malloc(n*sizeof(char)); /* 分配求编码的工作空间 */
cd[n-1]='\0';
for(i=1;i<=n;i++) /* 逐个字符求Huffman编码,注意i从1开始 */
{
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].code =(char*) malloc((n-start)*sizeof(char)); /* 为第i个字符编码分配空间 */
strcpy(HC[i].code,&cd[start]); /* 从cd 复制到HC[i].code */
}
free(cd);
}
/* ================================================================================ */
C语言利用哈夫曼树实现哈夫曼树生成和哈夫曼编码的实现
猜你喜欢
转载自blog.csdn.net/Xenoverse/article/details/83415597
今日推荐
周排行