哈夫曼编码 贪心算法 c语言实现
时间: 2023-11-15 22:02:40 浏览: 203
哈夫曼编码是一种广泛用于数据文件压缩的编码方法,其压缩率通常在20%~90%之间。它利用字符在文件中出现的频率表来建立一个用0,1串表示各字符的最优表示方式。哈夫曼编码实质上是利用最优二叉树原理,求最优前缀码的长度,即平均码长或文件总长最小的前缀编码。哈夫曼编码的实现过程可以使用贪心算法,即每次选择频率最小的两个字符进行合并,直到所有字符都被合并为止。C语言实现哈夫曼编码可以使用结构体来表示哈夫曼树节点,使用指针来实现树的构建和遍历,具体实现可以参考相关的C语言教材或者网上的代码示例。
相关问题
用贪心算法解哈夫曼编码问题c语言代码实现
在C语言中,贪心算法可以用来构建哈夫曼树并生成哈夫曼编码,这是通过每次选择两棵权值最小的树合并成新的树,并将这两棵树的权值作为新树的权值来实现的。以下是一个简单的C语言代码示例:
```c
#include <stdio.h>
#include <stdlib.h>
// 结点结构体
typedef struct {
int weight; // 权值
char symbol; // 符号
struct Node* left, *right; // 左右子节点
} Node;
// 创建新结点
Node* newNode(int weight, char symbol) {
Node* node = (Node*)malloc(sizeof(Node));
node->weight = weight;
node->symbol = symbol;
node->left = node->right = NULL;
return node;
}
// 贪心合并函数
Node* mergeTrees(Node* t1, Node* t2) {
if (!t1 || !t2)
return t1 ? t1 : t2;
if (t1->weight < t2->weight) {
t1->right = mergeTrees(t1->right, t2);
return t1;
} else {
t2->left = mergeTrees(t1, t2->left);
return t2;
}
}
// 构建哈夫曼树
Node* buildHuffmanTree(int weights[], int n) {
Node** heap = (Node**)malloc(n * sizeof(Node*));
for (int i = 0; i < n; ++i) {
heap[i] = newNode(weights[i], i + 'A');
}
while (heap[0]) {
int minIndex1 = 0, minIndex2 = 0;
for (int i = 1; i < n; ++i) {
if (heap[minIndex1]->weight > heap[i]->weight) {
minIndex1 = i;
}
}
for (int j = 1; j < n; ++j) {
if (heap[j] != heap[minIndex1] && heap[j]->weight < heap[minIndex2]->weight) {
minIndex2 = j;
}
}
Node* temp = mergeTrees(heap[minIndex1], heap[minIndex2]);
heap[minIndex1] = heap[minIndex2] = NULL;
heap[n++] = temp;
}
return heap[0];
}
// 打印哈夫曼编码
void printCodes(Node* root, int symbolToCode[]) {
if (!root)
return;
if (!root->left && !root->right)
symbolToCode[root->symbol - 'A'] = '0';
else {
printCodes(root->left, symbolToCode);
printCodes(root->right, symbolToCode);
}
}
int main() {
int weights[] = {5, 3, 4, 6}; // 示例权重数组
int n = sizeof(weights) / sizeof(weights[0]);
Node* huffTree = buildHuffmanTree(weights, n);
int symbolToCode[26] = {0};
printf("Huffman Tree:\n");
printCodes(huffTree, symbolToCode);
return 0;
}
```
这个代码首先创建了一个堆,然后不断从堆中取出两个权值最小的结点合并,直到只剩下一个结点。最后,它会递归地生成每个字符的哈夫曼编码。
贪心算法哈夫曼编码C语言
哈夫曼编码是一种基于贪心算法的压缩算法,其核心思想是将出现频率较高的字符用较短的编码表示,而出现频率较低的字符用较长的编码表示。以下是哈夫曼编码的C语言实现:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_TREE_HT 100
struct MinHeapNode {
char data;
unsigned freq;
struct MinHeapNode *left, *right;
};
struct MinHeap {
unsigned size;
unsigned capacity;
struct MinHeapNode **array;
};
struct MinHeapNode *newNode(char data, unsigned freq) {
struct MinHeapNode *temp = (struct MinHeapNode *)malloc(sizeof(struct MinHeapNode));
temp->left = temp->right = NULL;
temp->data = data;
temp->freq = freq;
return temp;
}
struct MinHeap *createMinHeap(unsigned capacity) {
struct MinHeap *minHeap = (struct MinHeap *)malloc(sizeof(struct MinHeap));
minHeap->size = 0;
minHeap->capacity = capacity;
minHeap->array = (struct MinHeapNode **)malloc(minHeap->capacity * sizeof(struct MinHeapNode *));
return minHeap;
}
void swapMinHeapNode(struct MinHeapNode **a, struct MinHeapNode **b) {
struct MinHeapNode *t = *a;
*a = *b;
*b = t;
}
void minHeapify(struct MinHeap *minHeap, int idx) {
int smallest = idx;
int left = 2 * idx + 1;
int right = 2 * idx + 2;
if (left < minHeap->size && minHeap->array[left]->freq < minHeap->array[smallest]->freq)
smallest = left;
if (right < minHeap->size && minHeap->array[right]->freq < minHeap->array[smallest]->freq)
smallest = right;
if (smallest != idx) {
swapMinHeapNode(&minHeap->array[smallest], &minHeap->array[idx]);
minHeapify(minHeap, smallest);
}
}
int isSizeOne(struct MinHeap *minHeap) {
return (minHeap->size == 1);
}
struct MinHeapNode *extractMin(struct MinHeap *minHeap) {
struct MinHeapNode *temp = minHeap->array[0];
minHeap->array[0] = minHeap->array[minHeap->size - 1];
--minHeap->size;
minHeapify(minHeap, 0);
return temp;
}
void insertMinHeap(struct MinHeap *minHeap, struct MinHeapNode *minHeapNode) {
++minHeap->size;
int i = minHeap->size - 1;
while (i && minHeapNode->freq < minHeap->array[(i - 1) / 2]->freq) {
minHeap->array[i] = minHeap->array[(i - 1) / 2];
i = (i - 1) / 2;
}
minHeap->array[i] = minHeapNode;
}
void buildMinHeap(struct MinHeap *minHeap) {
int n = minHeap->size - 1;
int i;
for (i = (n - 1) / 2; i >= 0; --i)
minHeapify(minHeap, i);
}
void printArr(int arr[], int n) {
int i;
for (i = 0; i < n; ++i)
printf("%d", arr[i]);
printf("\n");
}
int isLeaf(struct MinHeapNode *root) {
return !(root->left) && !(root->right);
}
struct MinHeap *createAndBuildMinHeap(char data[], int freq[], int size) {
struct MinHeap *minHeap = createMinHeap(size);
for (int i = 0; i < size; ++i)
minHeap->array[i] = newNode(data[i], freq[i]);
minHeap->size = size;
buildMinHeap(minHeap);
return minHeap;
}
struct MinHeapNode *buildHuffmanTree(char data[], int freq[], int size) {
struct MinHeapNode *left, *right, *top;
struct MinHeap *minHeap = createAndBuildMinHeap(data, freq, size);
while (!isSizeOne(minHeap)) {
left = extractMin(minHeap);
right = extractMin(minHeap);
top = newNode('$', left->freq + right->freq);
top->left = left;
top->right = right;
insertMinHeap(minHeap, top);
}
return extractMin(minHeap);
}
void printCodes(struct MinHeapNode *root, int arr[], int top) {
if (root->left) {
arr[top] = 0;
printCodes(root->left, arr, top + 1);
}
if (root->right) {
arr[top] = 1;
printCodes(root->right, arr, top + 1);
}
if (isLeaf(root)) {
printf("%c: ", root->data);
printArr(arr, top);
}
}
void HuffmanCodes(char data[], int freq[], int size) {
struct MinHeapNode *root = buildHuffmanTree(data, freq, size);
int arr[MAX_TREE_HT], top = 0;
printCodes(root, arr, top);
}
int main() {
char arr[] = {'a', 'b', 'c', 'd', 'e', 'f'};
int freq[] = {5, 9, 12, 13, 16, 45};
int size = sizeof(arr) / sizeof(arr[0]);
HuffmanCodes(arr, freq, size);
return 0;
}
```
以上代码实现了哈夫曼编码的生成过程,包括建立哈夫曼树、生成编码等步骤。
阅读全文