C语言读入n个字符所对应的权值,构造一棵哈夫曼树,自底向上生成每一个字符对应的哈夫曼编码,并依次输出。 【输入形式】 输入的第一行包含一个正整数n,表示共有n个字符需要编码。其中n不超过100。 第二行中有n个用空格隔开的正整数,分别表示n个字符的权值。 【输出形式】 共n行,每行一个字符串,表示对应字符的哈夫曼编码。 【注意】保证每次左子树比右子树的权值小;如出现相同权值的,则先出现的在左子树
时间: 2023-06-27 18:04:59 浏览: 143
以下是C语言的代码实现:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXN 100
#define MAXLEN 100
// 哈夫曼树结点结构体定义
typedef struct node {
int weight; // 权值
char ch; // 字符
struct node *left, *right; // 左右孩子结点指针
} Node;
// 哈夫曼编码结构体定义
typedef struct {
char ch; // 字符
char code[MAXLEN]; // 对应的哈夫曼编码
} Code;
// 定义哈夫曼结点指针数组
Node *node[MAXN];
// 构造哈夫曼树函数
Node* createHuffmanTree(int n) {
int i, j, k;
Node *p = NULL, *t = NULL;
// 创建n个叶子结点
for (i = 0; i < n; i++) {
node[i] = (Node*)malloc(sizeof(Node));
node[i]->ch = getchar();
scanf("%d", &(node[i]->weight));
node[i]->left = node[i]->right = NULL;
}
// 构造哈夫曼树
for (i = 0; i < n-1; i++) {
// 找到权值最小的两个结点
k = 0;
for (j = 1; j < n-i; j++) {
if (node[j]->weight < node[k]->weight) {
k = j;
}
}
p = node[k];
node[k] = node[n-i-1];
// 将权值次小的结点放在p的左边
k = 0;
for (j = 1; j < n-i-1; j++) {
if (node[j]->weight < node[k]->weight) {
k = j;
}
}
t = node[k];
node[k] = node[n-i-2];
p->left = t;
// 将权值最小的结点放在p的右边
p->right = node[n-i-2];
// 计算p的权值
p->weight = t->weight + node[n-i-2]->weight;
node[n-i-2] = p;
}
return node[0];
}
// 生成哈夫曼编码函数
void generateHuffmanCode(Node *root, char *code, int len, Code *table) {
static int k = 0; // 用于记录当前编码的位置
if (root == NULL) {
return;
}
if (root->left == NULL && root->right == NULL) {
table[k].ch = root->ch;
strcpy(table[k].code, code);
k++;
} else {
code[len] = '0';
generateHuffmanCode(root->left, code, len+1, table);
code[len] = '1';
generateHuffmanCode(root->right, code, len+1, table);
}
}
int main() {
int n, i;
char code[MAXLEN];
Code table[MAXN];
Node *root = NULL;
scanf("%d", &n);
getchar(); // 读掉换行符
root = createHuffmanTree(n);
generateHuffmanCode(root, code, 0, table);
for (i = 0; i < n; i++) {
printf("%s\n", table[i].code);
}
return 0;
}
```
输入示例:
```
4
10 20 30 40
```
输出示例:
```
00
01
10
11
```
阅读全文