用c语言实现:要求采用二叉链表作为存贮结构,完成霍夫曼树的创建。 2.输出对应数据的霍夫曼编码,并求出平均编码长度。
时间: 2024-02-29 17:51:10 浏览: 79
这是基本数据结构及其算法的C++实现,涉及单链表、双链表、栈 、二叉树、并查集、哈夫曼树、平衡二叉树、二叉搜索树等.zip
好的,我可以为您解答这个问题。
首先,我们需要了解霍夫曼树的创建过程。霍夫曼树是一种带权路径最短的树,也就是说,它的叶子节点对应的权值乘上其到根节点的路径长度之和最小。创建霍夫曼树的过程可以用贪心算法来实现:
1. 将所有节点按照权值从小到大排序,构建一个森林,每个节点都是一棵只有一个根节点的树。
2. 从森林中选出两个权值最小的树合并成一棵新树,新树的根节点是两棵树的根节点的父节点,其权值为两棵树的权值之和。
3. 将新树插入森林中,重复步骤2,直到只剩下一棵树为止。
接下来,我们可以用二叉链表来实现霍夫曼树的存储结构。定义一个结构体来表示霍夫曼树的节点:
```c
typedef struct HuffmanTreeNode {
int weight; // 权值
struct HuffmanTreeNode *left; // 左子树指针
struct HuffmanTreeNode *right; // 右子树指针
} HuffmanTreeNode;
```
然后,我们可以用一个链表来存储所有的节点,每次从链表中选取两个权值最小的节点进行合并。具体实现可以参考下面的代码:
```c
// 从链表中删除权值最小的节点
HuffmanTreeNode *removeMinNode(HuffmanTreeNode **list) {
HuffmanTreeNode *minNode = *list;
HuffmanTreeNode *prev = NULL;
HuffmanTreeNode *cur = *list;
while (cur != NULL) {
if (cur->weight < minNode->weight) {
minNode = cur;
prev = prev;
}
prev = cur;
cur = cur->next;
}
if (prev == NULL) {
*list = minNode->next;
} else {
prev->next = minNode->next;
}
minNode->next = NULL;
return minNode;
}
// 创建霍夫曼树
HuffmanTreeNode *createHuffmanTree(int *weights, int n) {
// 创建节点链表
HuffmanTreeNode *list = NULL;
for (int i = 0; i < n; i++) {
HuffmanTreeNode *node = (HuffmanTreeNode *)malloc(sizeof(HuffmanTreeNode));
node->weight = weights[i];
node->left = NULL;
node->right = NULL;
node->next = list;
list = node;
}
// 合并节点,直到只剩下一个节点
while (list->next != NULL) {
HuffmanTreeNode *node1 = removeMinNode(&list);
HuffmanTreeNode *node2 = removeMinNode(&list);
HuffmanTreeNode *newNode = (HuffmanTreeNode *)malloc(sizeof(HuffmanTreeNode));
newNode->weight = node1->weight + node2->weight;
newNode->left = node1;
newNode->right = node2;
newNode->next = list;
list = newNode;
}
return list;
}
```
接下来,我们需要输出每个字符对应的霍夫曼编码,并计算平均编码长度。霍夫曼编码是一种前缀编码,也就是说,每个字符的编码都不是另一个字符编码的前缀。因此,我们可以采用递归的方式来遍历霍夫曼树,对于每个叶子节点,输出它的权值和对应的编码。具体实现可以参考下面的代码:
```c
// 输出霍夫曼编码
void printHuffmanCode(HuffmanTreeNode *root, int code[], int len, float *avgLen) {
if (root->left == NULL && root->right == NULL) {
printf("%d: ", root->weight);
for (int i = 0; i < len; i++) {
printf("%d", code[i]);
}
printf("\n");
*avgLen += len * (float)root->weight;
} else {
code[len] = 0;
printHuffmanCode(root->left, code, len + 1, avgLen);
code[len] = 1;
printHuffmanCode(root->right, code, len + 1, avgLen);
}
}
```
最后,我们可以在主函数中调用上述函数来创建霍夫曼树,输出霍夫曼编码,并计算平均编码长度。具体实现可以参考下面的代码:
```c
int main() {
int weights[] = {5, 9, 12, 13, 16, 45};
int n = sizeof(weights) / sizeof(weights[0]);
HuffmanTreeNode *root = createHuffmanTree(weights, n);
int code[100];
float avgLen = 0.0;
printHuffmanCode(root, code, 0, &avgLen);
avgLen /= n;
printf("Average code length: %.2f\n", avgLen);
return 0;
}
```
以上就是用 C 语言实现霍夫曼树的创建,输出对应数据的霍夫曼编码,并求出平均编码长度的过程。
阅读全文