帮我用c语言写一个可以由我输入字符,和权值的哈夫曼树包含译码
时间: 2024-02-15 08:02:12 浏览: 67
好的,以下是一个简单的C语言程序,可以由用户输入字符和权值,然后构建哈夫曼树并包含译码功能:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct node {
char ch;
int weight;
struct node *left, *right;
} Node;
typedef struct huffman_tree {
Node *root;
} HuffmanTree;
typedef struct code_table {
char ch;
char code[256];
} CodeTable;
Node *new_node(char ch, int weight) {
Node *node = (Node *)malloc(sizeof(Node));
node->ch = ch;
node->weight = weight;
node->left = node->right = NULL;
return node;
}
HuffmanTree *new_huffman_tree() {
HuffmanTree *tree = (HuffmanTree *)malloc(sizeof(HuffmanTree));
tree->root = NULL;
return tree;
}
CodeTable *new_code_table(char ch, char *code) {
CodeTable *table = (CodeTable *)malloc(sizeof(CodeTable));
table->ch = ch;
strcpy(table->code, code);
return table;
}
void swap(Node **a, Node **b) {
Node *temp = *a;
*a = *b;
*b = temp;
}
void bubble_sort(Node **nodes, int n) {
for (int i = n - 1; i >= 0; i--) {
for (int j = 0; j < i; j++) {
if (nodes[j]->weight > nodes[j+1]->weight) {
swap(&nodes[j], &nodes[j+1]);
}
}
}
}
void print_tree(Node *root, char *code, int depth) {
if (root == NULL) return;
if (root->left == NULL && root->right == NULL) {
printf("%c: %s\n", root->ch, code);
return;
}
code[depth] = '0';
print_tree(root->left, code, depth + 1);
code[depth] = '1';
print_tree(root->right, code, depth + 1);
}
void build_huffman_tree(HuffmanTree *tree, char *chars, int *weights, int n) {
Node *nodes[n];
for (int i = 0; i < n; i++) {
nodes[i] = new_node(chars[i], weights[i]);
}
bubble_sort(nodes, n);
while (n > 1) {
Node *left = nodes[0];
Node *right = nodes[1];
Node *parent = new_node('\0', left->weight + right->weight);
parent->left = left;
parent->right = right;
nodes[0] = parent;
for (int i = 1; i < n - 1; i++) {
nodes[i] = nodes[i+1];
}
n--;
bubble_sort(nodes, n);
}
tree->root = nodes[0];
}
void generate_code_table(Node *root, char *code, int depth, CodeTable **table, int *index) {
if (root == NULL) return;
if (root->left == NULL && root->right == NULL) {
(*table)[*index] = *new_code_table(root->ch, code);
(*index)++;
return;
}
code[depth] = '0';
generate_code_table(root->left, code, depth + 1, table, index);
code[depth] = '1';
generate_code_table(root->right, code, depth + 1, table, index);
}
CodeTable *build_code_table(HuffmanTree *tree) {
char code[256] = {0};
int index = 0;
CodeTable *table = (CodeTable *)malloc(sizeof(CodeTable) * 256);
generate_code_table(tree->root, code, 0, &table, &index);
return table;
}
char *encode(char *str, CodeTable *table) {
int len = strlen(str);
char *encoded = (char *)malloc(len * 256);
int index = 0;
for (int i = 0; i < len; i++) {
for (int j = 0; j < 256; j++) {
if (str[i] == table[j].ch) {
strcat(encoded, table[j].code);
index += strlen(table[j].code);
break;
}
}
}
return encoded;
}
char *decode(char *str, HuffmanTree *tree) {
int len = strlen(str);
char *decoded = (char *)malloc(len);
Node *node = tree->root;
int index = 0;
for (int i = 0; i < len; i++) {
if (str[i] == '0') {
node = node->left;
} else {
node = node->right;
}
if (node->left == NULL && node->right == NULL) {
decoded[index] = node->ch;
index++;
node = tree->root;
}
}
decoded[index] = '\0';
return decoded;
}
int main() {
char chars[256];
int weights[256];
int n;
printf("Enter the number of characters: ");
scanf("%d", &n);
printf("Enter the characters and their weights:\n");
for (int i = 0; i < n; i++) {
scanf(" %c %d", &chars[i], &weights[i]);
}
HuffmanTree *tree = new_huffman_tree();
build_huffman_tree(tree, chars, weights, n);
printf("Huffman codes:\n");
char code[256] = {0};
print_tree(tree->root, code, 0);
CodeTable *table = build_code_table(tree);
printf("Enter a string to encode: ");
char str[256];
scanf("%s", str);
char *encoded = encode(str, table);
printf("Encoded string: %s\n", encoded);
char *decoded = decode(encoded, tree);
printf("Decoded string: %s\n", decoded);
free(tree);
free(table);
free(encoded);
free(decoded);
return 0;
}
```
注:该程序是基于字符和权值的哈夫曼编码,因此输入的字符不能重复。
阅读全文