代码
sorry,之前写的有bug。现在的已经完全没有bug了。
#include <stdio.h>
#include <stdlib.h>
#define MIN 32767
#define MAX 500
typedef struct
{
char data;
double weight;
int parent;
int lchild;
int rchild;
} HTNode;
typedef struct
{
char cd[MAX];
int start;
} HCode;
void Display0(int count[]); //统计各个字符出现次数
void Display1(HTNode ht[], HCode hcd[], int n0, char str[]); //显示各个字符的哈夫曼编码并输出电文
void Display2(HTNode ht[], int n0, char str[]); //输入电文解码输出字符串
void BuildHTArray(HTNode ht[], int count[]); //填充ht[]数组的前n0项的data域和weight域
void CreateHT(HTNode ht[], int n0); //构造哈夫曼树
void CreateHCode(HTNode ht[], HCode hcd[], int n0); //求哈夫曼编码
void Display0(int count[])
{
printf("Character\tfrequency\n");
for (int i = 0; i < 127; i++)
{
if (count[i] != 0)
{
printf("%c:\t%d\n", i, count[i]);
}
}
}
void Display1(HTNode ht[], HCode hcd[], int n0, char str[])
{
printf("character\tHuffmanCode\n");
for (int i = 0; i < n0; i++)
{
printf("%c:\t", ht[i].data);
for (int j = hcd[i].start; j <= n0; j++)
{
printf("%c", hcd[i].cd[j]);
}
printf("\n");
}
printf("\nThe HCode of this str is: ");
while (*str != '\0')
{
for (int i = 0; i < n0; i++)
{
if (ht[i].data == *str)
{
for (int k = hcd[i].start; k <= n0; k++ )
{
printf("%c", hcd[i].cd[k]);
}
break;
}
}
str++;
}
printf("\n");
}
void Display2(HTNode ht[], int n0, char str[])
{
int i = 0, j = 2 * n0 - 2, prej;
printf("The str of this HCode is: ");
while (str[i] != '\0')
{
while (j != -1)
{
prej = j;
if (str[i] == '0')
{
j = ht[j].lchild;
}
else
{
j = ht[j].rchild;
}
i++;
}
printf("%c", ht[prej].data);
i--;
j = 2 * n0 - 2;
}
printf("\n");
}
void BuildHTArray(HTNode ht[], int count[])
{
int j = 0;
for (int i = 0; i < 127; i++)
{
if (count[i] != 0)
{
ht[j].data = i;
ht[j].weight = count[i];
j++;
}
}
}
void CreateHT(HTNode ht[], int n0)
{
int i, k, lNode, rNode;
double min1, min2;
for (i = 0; i < 2 * n0 - 1; i++)
{
ht[i].lchild = ht[i].parent = ht[i].rchild = -1;
}
for (i = n0; i <= 2 * n0 - 2; i++)
{
min1 = min2 = MIN;
lNode = rNode = -1;
for (k = 0; k <= i - 1; k++)
{
if (ht[k].parent == -1)
{
if (ht[k].weight < min1)
{
min2 = min1;
rNode = lNode;
min1 = ht[k].weight;
lNode = k;
}
else if (ht[k].weight < min2)
{
min2 = ht[k].weight;
rNode = k;
}
}
}
ht[i].weight = ht[lNode].weight + ht[rNode].weight;
ht[i].lchild = lNode;
ht[i].rchild = rNode;
ht[lNode].parent = i;
ht[rNode].parent = i;
}
}
void CreateHCode(HTNode ht[], HCode hcd[], int n0)
{
int i, parent, child;
HCode hc;
for (i = 0; i < n0; i++)
{
hc.start = n0;
parent = ht[i].parent;
child = i;
while (parent != -1)
{
if (ht[parent].lchild == child)
{
hc.cd[hc.start--] = '0';
}
else
{
hc.cd[hc.start--] = '1';
}
child = parent;
parent = ht[child].parent;
}
hc.start++;
hcd[i] = hc;
}
}
int main(void)
{
FILE *fp;
char ch, str[MAX + 1];
int count[127] = {0}, n0 = 0, i = 0;
fp = fopen("text.txt", "r");
if (fp)
{
while (fscanf(fp, "%c", &ch) != EOF)
{
if (count[ch] == 0)
{
n0++;
}
count[ch]++;
str[i++] = ch;
}
str[i] = '\0';
}
fclose(fp);
HTNode *pHT = (HTNode *)malloc((2 * n0 - 1) * sizeof(HTNode));
HCode *pHCD = (HCode *)malloc((2 * n0 - 1) * sizeof(HCode));
if(pHT==NULL||pHCD==NULL){
return 1;
}
Display0(count);
printf("\n\n");
BuildHTArray(pHT, count);
CreateHT(pHT, n0);
CreateHCode(pHT, pHCD, n0);
Display1(pHT, pHCD, n0, str);
printf("\nPlease enter a string of Huffman code: ");
gets(str);
Display2(pHT, n0, str);
getchar();
getchar();
return 0;
}
text.txt
renshengruozhiruchujian
网友评论