c语言给定一组结点及对应的权值,创建一棵哈夫曼树,输出每个结点的哈夫曼编码,和整棵树的WPL值。
时间: 2023-06-13 20:02:57 浏览: 104
下面是一个简单的C语言实现,具体注释见代码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_NODE_NUM 100 // 最大结点数
// 哈夫曼树的结点
typedef struct node {
int weight; // 权值
struct node *left, *right; // 左右子结点
} Node;
// 保存哈夫曼编码的结构体
typedef struct code {
int bit[MAX_NODE_NUM]; // 存储每个结点的哈夫曼编码
int length; // 哈夫曼编码的长度
} Code;
// 选择两个权值最小的结点
void select_min(Node* nodes[], int n, int* p1, int* p2) {
int i, j;
*p1 = *p2 = -1; // 初始化为无效值
for (i = 0; i < n; i++) {
if (nodes[i] == NULL) continue; // 已经选过的结点跳过
if (*p1 == -1 || nodes[i]->weight < nodes[*p1]->weight) {
*p2 = *p1;
*p1 = i;
} else if (*p2 == -1 || nodes[i]->weight < nodes[*p2]->weight) {
*p2 = i;
}
}
}
// 创建哈夫曼树
Node* create_huffman_tree(int weights[], int n) {
int i, p1, p2;
Node* nodes[MAX_NODE_NUM];
for (i = 0; i < n; i++) {
nodes[i] = (Node*)malloc(sizeof(Node));
nodes[i]->weight = weights[i];
nodes[i]->left = nodes[i]->right = NULL;
}
while (1) {
select_min(nodes, n, &p1, &p2);
if (p1 == -1 || p2 == -1) break; // 所有结点都选完了
Node* new_node = (Node*)malloc(sizeof(Node));
new_node->weight = nodes[p1]->weight + nodes[p2]->weight;
new_node->left = nodes[p1];
new_node->right = nodes[p2];
nodes[p1] = new_node;
nodes[p2] = NULL; // 标记为已选
}
return nodes[p1]; // 最后剩下的结点即为根结点
}
// 递归输出哈夫曼编码
void print_huffman_code(Node* root, Code code) {
static int path[MAX_NODE_NUM]; // 保存路径
if (root->left == NULL && root->right == NULL) { // 叶子结点
printf("weight=%d, code=", root->weight);
int i;
for (i = 0; i < code.length; i++) {
printf("%d", code.bit[i]);
}
printf("\n");
} else {
path[code.length] = 0; // 左子树为0
code.bit[code.length] = 0;
code.length++;
print_huffman_code(root->left, code);
code.length--;
path[code.length] = 1; // 右子树为1
code.bit[code.length] = 1;
code.length++;
print_huffman_code(root->right, code);
code.length--;
}
}
// 计算哈夫曼树的WPL值
int count_wpl(Node* root, int depth) {
if (root->left == NULL && root->right == NULL) { // 叶子结点
return root->weight * depth;
} else {
return count_wpl(root->left, depth + 1) + count_wpl(root->right, depth + 1);
}
}
int main() {
int n, i;
int weights[MAX_NODE_NUM];
printf("请输入结点数n:");
scanf("%d", &n);
printf("请输入每个结点的权值:");
for (i = 0; i < n; i++) {
scanf("%d", &weights[i]);
}
Node* root = create_huffman_tree(weights, n);
Code code;
code.length = 0;
print_huffman_code(root, code);
printf("WPL=%d\n", count_wpl(root, 0));
return 0;
}
```
阅读全文