结合文档,给出文档中的题目:给定五个字符a~f,它们的权值集W={2,3,4,7,8,9},试构造关于W的一棵哈夫曼树,求其带权路径长度WPL和各个字符的哈夫曼编码。的具体c语言代码
时间: 2024-12-29 14:30:36 浏览: 50
为了帮助您完成题目,以下是针对给定五个字符及其权重,构建 Huffman 树并求其带权路径长度(WPL)和每个字符的哈夫曼编码的 C 语言代码示例:
### 结构体定义
首先定义节点(HTNode)、Huffman 编码(HCode)和哈夫曼树结构。
```c
#include <stdio.h>
#include <stdlib.h>
#define MAX_SIZE 100
// 定义霍夫曼树结点
typedef struct HTNode {
int weight;
char data;
int parent;
int lChild, rChild;
} HTNode, *HuffTree;
// 定义霍夫曼编码结构
typedef struct {
char cd[MAX_SIZE];
int start;
} HCode, *HuffmanCode;
```
### 构建 Huffman 树的函数
实现 `CreateHT` 和 `CreateHCode` 函数来构建 Huffman 树和生成相应的哈夫曼编码。
```c
void Select(HuffTree &HT, int len, int &i, int &j) {
i = j = -1;
for(int k = 0; k <= len; ++k)
if(HT[k].parent == -1){
if(i == -1)
i = k;
else if(j == -1 && HT[k].weight < HT[i].weight)
i = k;
else if(HT[k].weight < HT[i].weight || HT[k].weight < HT[j].weight)
j = k > i ? k : i,
i = k > i ? i : k;
}
}
void CreateHT(HuffTree &HT, int n) {
HT = (HuffTree)malloc((n * 2 + 1) * sizeof(HTNode));
memset(HT, 0, (2 * n + 1) * sizeof(HTNode));
for(int i = 0; i < n; ++i) {
scanf("%d", &HT[i].weight);
HT[i].parent = -1;
}
int m = 2 * n - 1;
for(int i = n; i < m; ++i) {
int s1, s2;
Select(HT, i - 1, s1, s2);
HT[s1].parent = HT[s2].parent = i;
HT[i].lChild = s1;
HT[i].rChild = s2;
HT[i].weight = HT[s1].weight + HT[s2].weight;
}
}
void CreatHcode(HuffTree &HT, HuffmanCode &HC, int n) {
HC = (HCode *)malloc(n * sizeof(HCode));
char cd[MAX_SIZE] = { '\0' };
for (int i = 0; i < n; i++) {
for (int c, f = i, p = 0; f != -1;) {
c = HT[f].parent;
cd[p++] = HT[c].rChild == f ? '1' : '0';
f = c;
}
HC[i].start = --p;
strncpy(HC[i].cd, &cd[0], strlen(cd));
}
}
```
### 测试数据输入及结果显示
下面是一个主函数的例子,其中包含了读取权值、显示结果等步骤。
```c
int main() {
int n = 6;
int w[n] = { 2, 3, 4, 7, 8, 9 }; // 权重集合
HuffTree HT;
HuffmanCode HC;
printf("Enter the weights:\n");
for(int i = 0; i < n; i++) {
HT[i].data = i; // 将索引设为数据,便于后续处理
HT[i].weight = w[i];
}
CreateHT(HT, n);
CreatHcode(HT, HC, n);
// 显示结果
int WPL = 0;
printf("The Huffman Codes are:\n");
for(int i = 0; i < n; i++) {
printf("char %d: ", i);
for(int j = HC[i].start; j >= 0; j--)
printf("%c", HC[i].cd[j]);
printf("\tweight: %d\tWPL contribute: %lld\n", w[i], atoll(HC[i].cd)*w[i]);
WPL += atol(HC[i].cd)*w[i];
}
printf("\nThe Weighted Path Length of the tree is %d\n", WPL);
return 0;
}
```
以上代码实现了一个完整的过程,包括输入字符权值、构建霍夫曼树、生成霍夫曼编码,并计算了总的带权路径长度 (WPL)。需要注意的是,在实际编程过程中,应确保所有的数组越界检查和异常处理都得到了妥善处理。
阅读全文