写一个c语言代码,根据八个字符的权值,w={5,29,7 ,8,14,23,3,11},自行构造一颗哈夫曼树,并打印构造结果
时间: 2024-12-15 17:22:20 浏览: 5
在C语言中,我们可以使用优先队列(如双端堆)和循环构建哈夫曼树。以下是一个简单的示例,展示如何创建一个哈夫曼树并打印结果。请注意,由于哈夫曼编码需要实时生成,这里我们只给出构建哈夫曼树的核心算法,实际的编码过程不在这个代码里。
```c
#include <stdio.h>
#include <stdlib.h>
// 定义节点结构体
typedef struct Node {
char data;
int weight; // 权值
struct Node* left;
struct Node* right;
} Node;
// 插入操作,用于构建最小堆
void insert(Node** heap, char data, int weight) {
Node* newNode = (Node*)malloc(sizeof(Node));
newNode->data = data;
newNode->weight = weight;
newNode->left = newNode->right = NULL;
if (*heap == NULL) {
*heap = newNode;
} else {
Node* temp = *heap;
while (temp && temp->weight < weight) {
if (temp->weight > newNode->weight) {
temp = temp->left;
} else {
temp = temp->right;
}
}
if (temp->weight > newNode->weight) { // 如果新节点应该插入到当前节点的左边
newNode->right = temp;
if (temp->left != NULL) {
temp->left = newNode;
} else {
*heap = newNode;
}
} else { // 否则插入到当前节点的右边
newNode->left = temp;
temp->parent = newNode;
if (temp == *heap) {
*heap = newNode;
} else if (temp->left == NULL) {
temp->parent->right = newNode;
} else {
temp = temp->left;
while (temp->right) {
temp = temp->right;
}
temp->right = newNode;
newNode->parent = temp->parent;
}
}
}
}
// 求两个节点合并后的权值
int combineWeights(Node* node1, Node* node2) {
return node1->weight + node2->weight;
}
// 构建哈夫曼树主函数
void buildHuffmanTree(Node** root, Node** heap) {
if (*heap == NULL || (*heap)->left == NULL) {
return;
}
Node* smaller = *heap;
Node* larger = smaller->left;
insert(heap, '\0', combineWeights(smaller, larger));
while (larger->left != NULL) {
smaller = larger;
larger = larger->left;
insert(heap, '\0', combineWeights(smaller, larger));
}
// 将哈夫曼树的结果复制回原堆,以便后续访问
for (Node* temp = *heap; temp != NULL; temp = temp->left) {
if (temp->right != NULL) {
temp->right->parent = temp->parent;
temp->right = NULL;
}
temp->left->parent = temp;
temp->left = smaller;
smaller = temp;
}
*root = smaller;
}
// 打印哈夫曼树
void printHuffmanTree(Node* root, char prefix) {
if (root == NULL) return;
printHuffmanTree(root->left, prefix + "0");
printf("%c: %d (%s)%s\n", root->data, root->weight, prefix, root->right ? " -> " : "");
printHuffmanTree(root->right, prefix + "1");
}
// 主函数
int main() {
Node* root = NULL;
Node* heap[8];
int w[] = {5, 29, 7, 8, 14, 23, 3, 11};
// 初始化堆
for (int i = 0; i < 8; i++) {
insert(&heap, w[i], i);
}
buildHuffmanTree(&root, &heap);
// 打印哈夫曼树
printf("哈夫曼树结果:\n");
printHuffmanTree(root, "");
return 0;
}
```
在这个代码中,我们首先创建了一个堆,然后通过不断从堆中取出两个最小的节点合并它们,直到堆中只剩下一个元素,即得到哈夫曼树的根节点。最后,我们遍历哈夫曼树并打印每个节点的数据和权值。
注意:这个代码并没有实现具体的哈夫曼编码,只是构建了哈夫曼树结构。如果你需要编码功能,你需要添加额外的逻辑来匹配特定的字符与其哈夫曼编码。
阅读全文