怎样用C语言创建哈夫曼编码
时间: 2023-07-19 14:39:17 浏览: 109
基于C语言的哈夫曼编码的实现.docx
创建哈夫曼编码的一般流程如下:
1. 统计每个字符出现的频率,将字符和对应频率存储在一个数据结构中。
2. 创建一个最小堆,将每个字符及其对应频率作为一个节点插入到堆中。
3. 从最小堆中取出两个频率最小的节点,并将它们合并成一个新的节点,频率为两个节点的频率之和。将新节点插入到最小堆中。
4. 重复第三步,直到堆中只剩下一个节点。
5. 对哈夫曼树进行遍历,将每个字符的编码存储在一个编码表中。
下面是一个使用C语言创建哈夫曼编码的示例代码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// 定义字符及其频率的结构体
typedef struct {
char ch;
int freq;
} CharFreq;
// 定义哈夫曼树节点的结构体
typedef struct _HuffmanNode {
CharFreq data;
struct _HuffmanNode *left;
struct _HuffmanNode *right;
} HuffmanNode;
// 定义最小堆的结构体
typedef struct {
HuffmanNode **data;
int size;
int capacity;
} MinHeap;
// 创建一个字符及其频率的结构体
CharFreq *createCharFreq(char ch, int freq) {
CharFreq *charFreq = (CharFreq *)malloc(sizeof(CharFreq));
charFreq->ch = ch;
charFreq->freq = freq;
return charFreq;
}
// 创建一个哈夫曼树节点
HuffmanNode *createHuffmanNode(CharFreq *charFreq) {
HuffmanNode *huffmanNode = (HuffmanNode *)malloc(sizeof(HuffmanNode));
huffmanNode->data = *charFreq;
huffmanNode->left = NULL;
huffmanNode->right = NULL;
return huffmanNode;
}
// 创建一个最小堆
MinHeap *createMinHeap(int capacity) {
MinHeap *minHeap = (MinHeap *)malloc(sizeof(MinHeap));
minHeap->data = (HuffmanNode **)malloc(sizeof(HuffmanNode *) * capacity);
minHeap->size = 0;
minHeap->capacity = capacity;
return minHeap;
}
// 交换最小堆中两个节点的位置
void swapNode(HuffmanNode **a, HuffmanNode **b) {
HuffmanNode *temp = *a;
*a = *b;
*b = temp;
}
// 向最小堆中插入一个节点
void insertNode(MinHeap *minHeap, HuffmanNode *huffmanNode) {
minHeap->data[minHeap->size++] = huffmanNode;
int i = minHeap->size - 1;
while (i > 0 && minHeap->data[i]->data.freq < minHeap->data[(i - 1) / 2]->data.freq) {
swapNode(&minHeap->data[i], &minHeap->data[(i - 1) / 2]);
i = (i - 1) / 2;
}
}
// 从最小堆中取出一个节点
HuffmanNode *popNode(MinHeap *minHeap) {
HuffmanNode *node = minHeap->data[0];
minHeap->data[0] = minHeap->data[--minHeap->size];
int i = 0;
while (i * 2 + 1 < minHeap->size) {
int j = i * 2 + 1;
if (j + 1 < minHeap->size && minHeap->data[j]->data.freq > minHeap->data[j + 1]->data.freq) {
j++;
}
if (minHeap->data[i]->data.freq > minHeap->data[j]->data.freq) {
swapNode(&minHeap->data[i], &minHeap->data[j]);
i = j;
} else {
break;
}
}
return node;
}
// 创建哈夫曼树
HuffmanNode *createHuffmanTree(CharFreq **charFreqs, int size) {
MinHeap *minHeap = createMinHeap(size);
for (int i = 0; i < size; i++) {
HuffmanNode *huffmanNode = createHuffmanNode(charFreqs[i]);
insertNode(minHeap, huffmanNode);
}
while (minHeap->size > 1) {
HuffmanNode *left = popNode(minHeap);
HuffmanNode *right = popNode(minHeap);
CharFreq *charFreq = createCharFreq('\0', left->data.freq + right->data.freq);
HuffmanNode *huffmanNode = createHuffmanNode(charFreq);
huffmanNode->left = left;
huffmanNode->right = right;
insertNode(minHeap, huffmanNode);
}
return popNode(minHeap);
}
// 将哈夫曼树转换为编码表
void createHuffmanCode(HuffmanNode *node, char *code, int depth) {
if (node == NULL) {
return;
}
if (node->left == NULL && node->right == NULL) {
printf("%c: %s\n", node->data.ch, code);
} else {
code[depth] = '0';
createHuffmanCode(node->left, code, depth + 1);
code[depth] = '1';
createHuffmanCode(node->right, code, depth + 1);
}
}
int main() {
CharFreq *charFreqs[] = {
createCharFreq('a', 5),
createCharFreq('b', 9),
createCharFreq('c', 12),
createCharFreq('d', 13),
createCharFreq('e', 16),
createCharFreq('f', 45),
};
int size = sizeof(charFreqs) / sizeof(charFreqs[0]);
HuffmanNode *root = createHuffmanTree(charFreqs, size);
char code[100];
createHuffmanCode(root, code, 0);
return 0;
}
```
以上代码演示了如何使用C语言创建哈夫曼编码。在这个示例中,我们首先创建了一个字符及其频率的结构体,然后使用最小堆将每个字符及其对应频率作为一个节点插入到堆中。接下来,我们从最小堆中取出两个频率最小的节点,并将它们合并成一个新的节点,频率为两个节点的频率之和。然后将新节点插入到最小堆中,并重复这个过程,直到堆中只剩下一个节点。最后,我们对哈夫曼树进行遍历,将每个字符的编码存储在一个编码表中。
阅读全文