C语言完成以下代码:给出n个结点的描述,构造一棵哈夫曼树。输入第一行是一个正整数t。 接下来有t组数据,每组数据有两行。 第一行是一个正整数n,表示有n个结点。 第二行是n个整数,第i个整数mi表示编号为i的结点权重为mi。 (0<t<100, 1<=n<=1000, 0<mi<=100)每组数据输出一个整数,表示哈夫曼树的带权路径长度。
时间: 2024-02-01 22:14:36 浏览: 87
以下是C语言实现:
```c
#include <stdio.h>
#include <stdlib.h>
#define MAX_N 1000
typedef struct huffman_node {
int weight;
int parent;
int left_child;
int right_child;
} HuffmanNode;
void build_huffman_tree(HuffmanNode *nodes, int n);
int get_min_weight_node(HuffmanNode *nodes, int n, int *index1, int *index2);
int main() {
int t;
scanf("%d", &t);
while (t--) {
int n, i;
scanf("%d", &n);
HuffmanNode nodes[MAX_N];
for (i = 0; i < n; i++) {
scanf("%d", &nodes[i].weight);
nodes[i].parent = -1;
nodes[i].left_child = -1;
nodes[i].right_child = -1;
}
build_huffman_tree(nodes, n);
int wpl = 0;
for (i = 0; i < n; i++) {
int depth = 0;
int j = i;
while (nodes[j].parent != -1) {
depth++;
j = nodes[j].parent;
}
wpl += nodes[i].weight * depth;
}
printf("%d\n", wpl);
}
return 0;
}
void build_huffman_tree(HuffmanNode *nodes, int n) {
int i, index1, index2;
for (i = n; i < 2 * n - 1; i++) {
get_min_weight_node(nodes, i, &index1, &index2);
nodes[i].weight = nodes[index1].weight + nodes[index2].weight;
nodes[index1].parent = i;
nodes[index2].parent = i;
nodes[i].left_child = index1;
nodes[i].right_child = index2;
}
}
int get_min_weight_node(HuffmanNode *nodes, int n, int *index1, int *index2) {
int i, min1, min2;
*index1 = -1;
*index2 = -1;
min1 = min2 = 0x7fffffff;
for (i = 0; i < n; i++) {
if (nodes[i].parent == -1) {
if (nodes[i].weight < min1) {
min2 = min1;
min1 = nodes[i].weight;
*index2 = *index1;
*index1 = i;
} else if (nodes[i].weight < min2) {
min2 = nodes[i].weight;
*index2 = i;
}
}
}
return min1 + min2;
}
```
该代码采用了一个结构体 `HuffmanNode` 来表示哈夫曼树的节点,其中包括权重、父节点、左右子节点等信息。`build_huffman_tree` 函数实现了构建哈夫曼树的算法,采用了贪心策略,即每次选择权重最小的两个节点合并,直到只剩下一个节点。`get_min_weight_node` 函数用于寻找当前未被合并的节点中权重最小的两个。
最后计算哈夫曼树的带权路径长度(WPL),即将每个节点的权重乘以其深度,再将所有节点的结果相加即可。
阅读全文