用C语言写出以下程序,用邻接表表示法表示图,已知数据六个字母及在通信中出现频率如下表:A,B,C,D,E,F的频率分别为0.15,0.3,0.1,0.1,0.2,0.15,把这些字母和频率作为叶子结点及权值。计算带权路径长度WPL(要有过程)
时间: 2023-11-22 18:05:31 浏览: 202
以下是用C语言实现该程序的代码,具体实现方式是通过邻接表表示法构建哈夫曼树,并计算带权路径长度WPL:
```c
#include <stdio.h>
#include <stdlib.h>
#define MAX_SIZE 100
// 邻接表结构体
typedef struct node {
int weight;
int parent, lchild, rchild;
} huffmanTree[MAX_SIZE];
// 构建哈夫曼树
void createHuffmanTree(huffmanTree ht, int n) {
int i, j, x1, x2, min1, min2;
for (i = 0; i < 2 * n - 1; i++) {
ht[i].parent = -1;
ht[i].lchild = -1;
ht[i].rchild = -1;
}
for (i = 0; i < n; i++) {
printf("请输入第%d个叶子结点的权值:", i + 1);
scanf("%d", &ht[i].weight);
}
for (i = 0; i < n - 1; i++) {
x1 = -1;
x2 = -1;
min1 = min2 = 9999;
for (j = 0; j < n + i; j++) {
if (ht[j].parent == -1 && ht[j].weight < min1) {
min2 = min1;
x2 = x1;
min1 = ht[j].weight;
x1 = j;
} else if (ht[j].parent == -1 && ht[j].weight < min2) {
min2 = ht[j].weight;
x2 = j;
}
}
ht[x1].parent = n + i;
ht[x2].parent = n + i;
ht[n + i].weight = ht[x1].weight + ht[x2].weight;
ht[n + i].lchild = x1;
ht[n + i].rchild = x2;
}
}
// 计算带权路径长度WPL
int calcWPL(huffmanTree ht, int n) {
int i, j, wpl = 0;
for (i = 0; i < n; i++) {
int parent = ht[i].parent;
for (j = i; parent != -1; j = parent, parent = ht[parent].parent) {
if (ht[parent].lchild == j) {
wpl += 0; // 左子树为0
} else {
wpl += 1; // 右子树为1
}
}
}
return wpl;
}
int main() {
int n = 6; // 叶子结点个数
huffmanTree ht;
createHuffmanTree(ht, n);
int wpl = calcWPL(ht, n);
printf("带权路径长度WPL为:%d\n", wpl);
return 0;
}
```
在该程序中,我们首先定义了一个邻接表结构体huffmanTree,其中包含每个结点的权值、父结点、左子结点和右子结点。接着,我们通过createHuffmanTree函数构建哈夫曼树,并在输入每个叶子结点的权值后,使用贪心算法找到最小的两个权值,将它们合并为一个新节点,直到构建出整棵哈夫曼树。最后,我们通过calcWPL函数计算带权路径长度WPL,它的计算方式是遍历每个叶子结点,计算从叶子结点到根节点的路径长度,并将路径长度乘以叶子结点的权值,最后将所有叶子结点的路径长度和相加就得到了WPL。
阅读全文