大家好,我是贤弟!
一、什么是哈夫曼编码算法?
哈夫曼编码算法是一种用于数据压缩的算法,它通过对数据中出现频率较高的字符进行编码,从而减小数据的存储空间。
二、哈夫曼编码算法的原理
哈夫曼编码算法的原理如下:
1. 统计字符出现的频率,将频率作为权值构建一颗哈夫曼树。
2. 对于哈夫曼树中的每个叶子节点,将其对应的字符编码为一串二进制码,编码的方式为从根节点出发,向左走为0,向右走为1,直到到达叶子节点。
3. 将编码后的数据存储起来,以便后续解码。
4. 解码时,从编码后的数据中读取一串二进制码,从哈夫曼树的根节点开始,按照二进制码的顺序依次向左或向右走,直到到达叶子节点,即可得到对应的字符。
三、代码示例
以下是用C语言实现哈夫曼编码算法的代码:
#include #include #include
#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* node = (struct MinHeapNode*)malloc(sizeof(struct MinHeapNode)); node->left = node->right = NULL; node->data = data; node->freq = freq; return node;}
// 创建一个新的哈夫曼树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;}
// 构建哈夫曼树struct MinHeapNode* buildHuffmanTree(char data[], int freq[], int size) { struct MinHeapNode *left, *right, *top; struct MinHeap* minHeap = createMinHeap(size); for (int i = 0; i < size; ++i) insertMinHeap(minHeap, newNode(data[i], freq[i])); 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);}
// 判断节点是否为叶子节点int isLeaf(struct MinHeapNode* root) { return !(root->left) && !(root->right);}
// 打印哈夫曼编码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); for (int i = 0; i < top; ++i) printf("%d", arr[i]); printf("\n"); }}
// 哈夫曼编码主函数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 data[] = {'a', 'b', 'c', 'd', 'e', 'f'}; int freq[] = {5, 9, 12, 13, 16, 45}; int size = sizeof(data) / sizeof(data[0]); HuffmanCodes(data, freq, size); return 0;}
领取专属 10元无门槛券
私享最新 技术干货