数据结构编程题:哈夫曼编码
【问题描述】
| 符号 | A | B | C | D | E |
|---|---|---|---|---|---|
| 计数 | 15 | 7 | 6 | 6 | 5 |
| 概率 | 0.38461538 | 0.17948718 | 0.15384615 | 0.15384615 | 0.12820513 |
| 符号 | A | B | C | D | E |
|---|---|---|---|---|---|
| 代码 | 0 | 100 | 101 | 110 | 111 |
【输入形式】
5
15 7 6 6 5
【输出形式】
0
100
101
110
111
【注】这题我采用C语言来实现
代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_TREE_NODES 100
typedef struct HuffmanNode {
char data;
int freq;
int index; // 添加索引字段来记录原始顺序
struct HuffmanNode *left, *right;
} HuffmanNode;
typedef struct {
int size;
int capacity;
HuffmanNode **array;
} MinHeap;
HuffmanNode* newNode(char data, int freq, int index) {
HuffmanNode* node = (HuffmanNode*)malloc(sizeof(HuffmanNode));
node->data = data;
node->freq = freq;
node->index = index; // 设置索引
node->left = node->right = NULL;
return node;
}
MinHeap* createMinHeap(int capacity) {
MinHeap* minHeap = (MinHeap*)malloc(sizeof(MinHeap));
minHeap->size = 0;
minHeap->capacity = capacity;
minHeap->array = (HuffmanNode**)malloc(capacity * sizeof(HuffmanNode*));
return minHeap;
}
void swapHuffmanNode(HuffmanNode** a, HuffmanNode** b) {
HuffmanNode* t = *a;
*a = *b;
*b = t;
}
void minHeapify(MinHeap* minHeap, int idx) {
int smallest = idx;
int left = 2 * idx + 1;
int right = 2 * idx + 2;
if (left < minHeap->size) {
if (minHeap->array[left]->freq < minHeap->array[smallest]->freq ||
(minHeap->array[left]->freq == minHeap->array[smallest]->freq &&
minHeap->array[left]->index < minHeap->array[smallest]->index))
smallest = left;
}
if (right < minHeap->size) {
if (minHeap->array[right]->freq < minHeap->array[smallest]->freq ||
(minHeap->array[right]->freq == minHeap->array[smallest]->freq &&
minHeap->array[right]->index < minHeap->array[smallest]->index))
smallest = right;
}
if (smallest != idx) {
swapHuffmanNode(&minHeap->array[smallest], &minHeap->array[idx]);
minHeapify(minHeap, smallest);
}
}
int isSizeOne(MinHeap* minHeap) {
return minHeap->size == 1;
}
HuffmanNode* extractMin(MinHeap* minHeap) {
HuffmanNode* temp = minHeap->array[0];
minHeap->array[0] = minHeap->array[minHeap->size - 1];
--minHeap->size;
minHeapify(minHeap, 0);
return temp;
}
void insertMinHeap(MinHeap* minHeap, HuffmanNode* node) {
++minHeap->size;
int i = minHeap->size - 1;
while (i && (node->freq < minHeap->array[(i - 1) / 2]->freq ||
(node->freq == minHeap->array[(i - 1) / 2]->freq &&
node->index < minHeap->array[(i - 1) / 2]->index))) {
minHeap->array[i] = minHeap->array[(i - 1) / 2];
i = (i - 1) / 2;
}
minHeap->array[i] = node;
}
int isLeaf(HuffmanNode* root) {
return!(root->left) &&!(root->right);
}
MinHeap* createAndBuildMinHeap(char data[], int freq[], int size) {
MinHeap* minHeap = createMinHeap(size);
for (int i = 0; i < size; ++i)
minHeap->array[i] = newNode(data[i], freq[i], i);
minHeap->size = size;
int i;
for (i = (size - 2) / 2; i >= 0; --i)
minHeapify(minHeap, i);
return minHeap;
}
HuffmanNode* buildHuffmanTree(char data[], int freq[], int size) {
HuffmanNode *left, *right, *top;
MinHeap* minHeap = createAndBuildMinHeap(data, freq, size);
while (!isSizeOne(minHeap)) {
left = extractMin(minHeap);
right = extractMin(minHeap);
top = newNode('$', left->freq + right->freq, -1); // 内部节点索引设为-1
// 频率小的节点作为左子节点,频率相同时索引小的作为左子节点
if (left->freq < right->freq ||
(left->freq == right->freq && left->index < right->index)) {
top->left = left;
top->right = right;
} else {
top->left = right;
top->right = left;
}
insertMinHeap(minHeap, top);
}
return extractMin(minHeap);
}
void storeCodes(HuffmanNode* root, int arr[], int top, char** codes, char data[], int size) {
if (root->left) {
arr[top] = 0;
storeCodes(root->left, arr, top + 1, codes, data, size);
}
if (root->right) {
arr[top] = 1;
storeCodes(root->right, arr, top + 1, codes, data, size);
}
if (isLeaf(root)) {
int index = 0;
while (index < size && data[index] != root->data) index++;
codes[index] = (char*)malloc((top + 1) * sizeof(char));
for (int i = 0; i < top; i++) {
codes[index][i] = arr[i] + '0';
}
codes[index][top] = '\0';
}
}
void HuffmanCodes(char data[], int freq[], int size) {
HuffmanNode* root = buildHuffmanTree(data, freq, size);
int arr[MAX_TREE_NODES], top = 0;
char* codes[MAX_TREE_NODES];
storeCodes(root, arr, top, codes, data, size);
for (int i = 0; i < size; i++) {
printf("%s\n", codes[i]);
free(codes[i]);
}
}
int main() {
int n;
scanf("%d", &n);
char data[MAX_TREE_NODES];
int freq[MAX_TREE_NODES];
for (int i = 0; i < n; i++) {
data[i] = 'A' + i;
}
for (int i = 0; i < n; i++) {
scanf("%d", &freq[i]);
}
HuffmanCodes(data, freq, n);
return 0;
}
结果如下:


被折叠的 条评论
为什么被折叠?



