C语言写一个哈夫曼树编码译码系统,要求可以自行写入权值和字符,并对输入的编码进行译码
时间: 2024-05-16 15:18:31 浏览: 128
下面是一个基于C语言实现的哈夫曼树编码译码系统,包含了输入权值和字符、哈夫曼树的构建、编码和译码等功能。
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// 定义哈夫曼树结点结构体
typedef struct TreeNode {
char data; // 结点存储的字符
int weight; // 结点的权值
struct TreeNode *left; // 左子树指针
struct TreeNode *right; // 右子树指针
} TreeNode;
// 定义哈夫曼编码结构体
typedef struct {
char data; // 字符
char code[256]; // 编码(最大长度不超过256)
} HuffmanCode;
// 构建哈夫曼树
TreeNode *buildHuffmanTree(char *chars, int *weights, int n) {
TreeNode **treeNodes = (TreeNode **)malloc(n * sizeof(TreeNode *));
for (int i = 0; i < n; i++) {
treeNodes[i] = (TreeNode *)malloc(sizeof(TreeNode));
treeNodes[i]->data = chars[i];
treeNodes[i]->weight = weights[i];
treeNodes[i]->left = NULL;
treeNodes[i]->right = NULL;
}
while (n > 1) {
int minIndex1 = -1, minIndex2 = -1;
for (int i = 0; i < n; i++) {
if (treeNodes[i] != NULL) {
if (minIndex1 == -1 || treeNodes[i]->weight < treeNodes[minIndex1]->weight) {
minIndex2 = minIndex1;
minIndex1 = i;
} else if (minIndex2 == -1 || treeNodes[i]->weight < treeNodes[minIndex2]->weight) {
minIndex2 = i;
}
}
}
TreeNode *newNode = (TreeNode *)malloc(sizeof(TreeNode));
newNode->data = '\0';
newNode->weight = treeNodes[minIndex1]->weight + treeNodes[minIndex2]->weight;
newNode->left = treeNodes[minIndex1];
newNode->right = treeNodes[minIndex2];
treeNodes[minIndex1] = newNode;
treeNodes[minIndex2] = NULL;
n--;
}
return treeNodes[minIndex1];
}
// 递归生成哈夫曼编码
void generateHuffmanCode(TreeNode *root, char *code, int depth, HuffmanCode *codes) {
if (root->left == NULL && root->right == NULL) {
codes[root->data].data = root->data;
strncpy(codes[root->data].code, code, depth);
codes[root->data].code[depth] = '\0';
return;
}
code[depth] = '0';
generateHuffmanCode(root->left, code, depth + 1, codes);
code[depth] = '1';
generateHuffmanCode(root->right, code, depth + 1, codes);
}
// 哈夫曼编码
void huffmanEncode(char *str, HuffmanCode *codes, char *result) {
int len = strlen(str);
result[0] = '\0';
for (int i = 0; i < len; i++) {
strcat(result, codes[str[i]].code);
}
}
// 哈夫曼译码
void huffmanDecode(char *str, TreeNode *root, char *result) {
TreeNode *p = root;
int len = strlen(str);
result[0] = '\0';
for (int i = 0; i < len; i++) {
if (str[i] == '0') {
p = p->left;
} else {
p = p->right;
}
if (p->left == NULL && p->right == NULL) {
result[strlen(result)] = p->data;
p = root;
}
}
}
int main() {
char chars[256]; // 字符数组
int weights[256]; // 权值数组
int n = 0; // 字符个数
printf("请输入字符和权值(字符和权值间用空格分隔,每组输入占一行,以#结束):\n");
while (1) {
char c;
int w;
scanf("%c%d", &c, &w);
if (c == '#') {
break;
}
chars[n] = c;
weights[n] = w;
n++;
getchar(); // 读取换行符
}
getchar(); // 读取多余的换行符
TreeNode *root = buildHuffmanTree(chars, weights, n); // 构建哈夫曼树
char code[256] = {0}; // 编码数组
HuffmanCode codes[256]; // 哈夫曼编码数组
generateHuffmanCode(root, code, 0, codes); // 生成哈夫曼编码
char str[256]; // 待编码的字符串
char result[256] = {0}; // 编码后的结果
printf("请输入要编码的字符串:");
fgets(str, 256, stdin);
str[strlen(str) - 1] = '\0'; // 将输入的换行符替换为字符串结束符
huffmanEncode(str, codes, result); // 编码
printf("编码结果:%s\n", result);
char decode[256] = {0}; // 解码后的结果
huffmanDecode(result, root, decode); // 译码
printf("译码结果:%s\n", decode);
return 0;
}
```
在运行程序时,按照提示输入字符和权值,以#结束。然后输入要编码的字符串即可。程序将输出编码结果和译码结果。
需要注意的是,在输入完字符和权值后,需要读取多余的换行符,以免影响后面输入字符串的读取。此外,在输入字符串时,需要将输入的换行符替换为字符串结束符,否则会影响译码的结果。
阅读全文