//头文件
#pragma once
typedef struct {
char ch;
int freq;
} CharNode;
typedef struct {
int freq;
CharNode* charNode;
} MinHeapNode;
typedef struct {
MinHeapNode* nodes;
int size;
int capacity;
} MinHeap;
typedef struct BinTreeNode {
char data;
struct BinTreeNode* left;
struct BinTreeNode* right;
} BinTreeNode;
// 函数声明
void swap(MinHeapNode**, MinHeapNode**);
void minHeapify(MinHeap*, int);
MinHeapNode* extractMin(MinHeap*);
void decreaseKey(MinHeap*, int, MinHeapNode*);
void buildMinHeap(MinHeap*);
MinHeapNode* createMinHeapNode(CharNode*);
void printHeap(MinHeap*);
BinTreeNode* createHuffmanTree(MinHeap*);
//源代码.cpp
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include "erchashuqueson2.h"
// 全局变量
#define MinHeap* heap;
int main() {
int n; int i;
printf("Enter the number of characters: ");
scanf("%d", &n);
CharNode charNodes[n]; // 存储字符和频率
printf("Enter the characters and their frequencies:\n");
for (i = 0; i < n; i++) {
scanf("%c %d", &charNodes[i].ch, &charNodes[i].freq);
}
&heap = (*heap)malloc(sizeof(MinHeap));
&heap->nodes = (MinHeapNode*);malloc(sizeof(MinHeapNode) * n);
&heap->size = 0;
&heap->capacity = n;
// 将字符节点转换为最小堆节点并构建最小堆
for (i = 0; i < n; i++) {
MinHeapNode* node = createMinHeapNode(&charNodes[i]);
heap->nodes[heap->size++] = *node;
}
buildMinHeap(heap);
// 使用最小堆构建哈夫曼树
BinTreeNode* HuffmanTree = createHuffmanTree(heap);
// 输出哈夫曼树的数组初态
printf("Initial heap state:\n");
printHeap(heap);
// 这里可以添加代码来输出哈夫曼树的终态,例如遍历树的代码
// 清理内存
free(heap->nodes);
free(heap);
// 注意:这里没有释放BinTreeNode分配的内存,实际使用中需要添加这部分代码
return 0;
}
// 交换两个最小堆节点
void swap(MinHeapNode* a, MinHeapNode* b) {
MinHeapNode temp = *a;
*a = *b;
*b = temp;
}
// 向下调整最小堆
void minHappify(MinHeap* h, int idx;)
{
int smallest = idx;
int left = 2 * idx + 1;
int right = 2 * idx + 2;
if (left < h->size && h->nodes[left].freq < h->nodes[smallest].freq) {
smallest = left;
}
if (right < h->size && h->nodes[right].freq < h->nodes[smallest].freq) {
smallest = right;
}
if (smallest != idx) {
swap(&h->nodes[idx], &h->nodes[smallest]);
minHeapify(h, smallest);
}
}
// 从最小堆中提取最小元素
MinHeapNode* extractMin(MinHeap* h) {
if (h->size == 0) return NULL;
MinHeapNode* minNode = h->nodes[0];
h->nodes[0] = h->nodes[h->size - 1];
h->size--;
minHeapify(h, 0);
return minNode;
}
// 构建最小堆
void buildMinHeap(MinHeap* h) {
int i;
for (i = h->size / 2 - 1; i >= 0; i--) {
minHeapify(h, i);
}
}
// 创建一个新的最小堆节点
MinHeapNode* createMinHeapNode(CharNode* cNode) {
MinHeapNode* node = (MinHeapNode*)malloc(sizeof(MinHeapNode));
node->freq = cNode->freq;
node->charNode = cNode;
return node;
}
// 打印最小堆
void printHeap(MinHeap* h) {
for (int i = 0; i < h->size; i++) {
printf("(%c, %d) ", h->nodes[i]->charNode->ch, h->nodes[i]->freq);
}
printf("\n");
}
// 使用最小堆构建哈夫曼树
BinTreeNode* createHuffmanTree(MinHeap* h) {
BinTreeNode* left, * right, * top;
while (h->size > 1) {
left = createHuffmanTree(h); // 取出最小频率的节点
right = createHuffmanTree(h);
top = (BinTreeNode*)malloc(sizeof(BinTreeNode));
top->data = '\0'; // 内部节点用空字符表示
top->left = left;
top->right = right;
top->left->right = top->right->left = NULL; // 重置子节点的左右指针
MinHeapNode* newNode = createMinHeapNode((CharNode*)malloc(sizeof(CharNode)));
newNode->freq = left->freq + right->freq; // 新节点的频率是左右子树频率之和
newNode->charNode = NULL; // 内部节点没有字符
insertNode(h, newNode); // 将新节点加入最小堆
}
return h->nodes[0] ? h->nodes[0]->charNode : NULL;
}
// 插入节点到最小堆中
void insertNode(MinHeap* h, MinHeapNode* node) {
if (h->size >= h->capacity) {
printf("Heap overflow\n");
return;
}
h->nodes[h->size] = *node;
int i = h->size++;
while (i != 0 && h->nodes[(i - 1) / 2].freq > h->nodes[i].freq) {
swap(&h->nodes[(i - 1) / 2], &h->nodes[i]);
i = (i - 1) / 2;
}
}