用C语言编写一个哈夫曼编码要求 1、 构造哈夫曼树时使用顺序表作为哈夫曼树的存储结构。 2、 求哈夫曼编码时使用一维结构数组作为哈夫曼编码信息的存储
时间: 2023-07-19 07:20:20 浏览: 106
好的,我会为您解答关于C语言编写哈夫曼编码的问题。
首先,哈夫曼编码是一种用于数据压缩的算法,它将出现频率较高的字符用较短的编码表示,出现频率较低的字符用较长的编码表示,从而达到压缩数据的目的。
以下是构造哈夫曼树的C语言代码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_SIZE 100
typedef struct {
int weight; // 权值
int parent; // 父节点
int lchild; // 左子节点
int rchild; // 右子节点
} HTNode;
int main() {
int n; // 字符个数
int i, j, k;
int min1, min2; // 最小的两个权值的下标
int sum; // 权值之和
HTNode ht[MAX_SIZE*2]; // 哈夫曼树的存储
int select[MAX_SIZE*2]; // 标记节点是否被选择
// 输入字符个数
printf("请输入字符个数:");
scanf("%d", &n);
// 输入每个字符的权值
for (i = 0; i < n; i++) {
printf("请输入第%d个字符的权值:", i+1);
scanf("%d", &ht[i].weight);
ht[i].parent = ht[i].lchild = ht[i].rchild = -1;
select[i] = 0;
}
// 构造哈夫曼树
for (i = n; i < 2*n-1; i++) {
min1 = min2 = -1;
for (j = 0; j < i; j++) {
if (select[j] == 0) {
if (min1 == -1 || ht[j].weight < ht[min1].weight) {
min2 = min1;
min1 = j;
} else if (min2 == -1 || ht[j].weight < ht[min2].weight) {
min2 = j;
}
}
}
ht[min1].parent = ht[min2].parent = i;
ht[i].lchild = min1;
ht[i].rchild = min2;
ht[i].weight = ht[min1].weight + ht[min2].weight;
select[min1] = select[min2] = 1;
}
return 0;
}
```
上述代码中,先输入字符个数和每个字符的权值,然后构造哈夫曼树。在构造哈夫曼树时,使用数组select标记节点是否被选择,初始化为0表示未被选择。每次从未被选择的节点中选取两个权值最小的节点,作为新节点的左右子节点,并计算新节点的权值,将新节点标记为未选择。重复以上步骤,直到构造出完整的哈夫曼树。
接下来是求哈夫曼编码的C语言代码:
```c
typedef struct {
char ch; // 字符
char code[MAX_SIZE]; // 编码
} CodeNode;
void get_code(HTNode ht[], int n, CodeNode huff_code[]) {
int i, j, k;
int p, c;
char temp[MAX_SIZE];
for (i = 0; i < n; i++) {
huff_code[i].ch = i + 'a';
p = ht[i].parent;
k = 0;
while (p != -1) {
if (ht[p].lchild == i) {
temp[k++] = '0';
} else {
temp[k++] = '1';
}
i = p;
p = ht[p].parent;
}
temp[k] = '\0';
strcpy(huff_code[i].code, strrev(temp));
}
}
```
在求哈夫曼编码时,先定义一个结构体CodeNode,用于存储每个字符的编码。然后遍历哈夫曼树中的每个叶子节点,从叶子节点开始向上遍历,记录每个节点是其父节点的左子节点还是右子节点,将0表示为左子节点,1表示为右子节点。遍历到根节点时,将记录的编码颠倒过来,即为该字符的哈夫曼编码。
以上是C语言编写哈夫曼编码的基本思路和代码实现。
阅读全文