Linux 下编程练习--Minheap/HuffManTree/HuffManCode

本文将介绍如何利用小堆数据结构实现哈夫曼编码,并解释其原理及应用。

练习实现小堆 并用小堆实现哈夫曼数,实现哈夫曼编码








结果///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


#include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX_TREE_NODES 256 #define MAX_CODE_LENGTH 256 // 哈夫曼节点结构体 typedef struct HuffmanNode { char data; float freq; struct HuffmanNode *left, *right; } HuffmanNode; // 最小结构体 typedef struct { HuffmanNode **array; int size; int capacity; } MinHeap; // 创建一个新的哈夫曼节点 HuffmanNode* newNode(char data, float freq) { HuffmanNode* node = (HuffmanNode*)malloc(sizeof(HuffmanNode)); node->data = data; node->freq = freq; 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 && 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) { swapHuffmanNode(&minHeap->array[smallest], &minHeap->array[idx]); minHeapify(minHeap, smallest); } } // 检查的大小是否为1 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) { minHeap->array[i] = minHeap->array[(i - 1) / 2]; i = (i - 1) / 2; } minHeap->array[i] = node; } // 构建最小 void buildMinHeap(MinHeap* minHeap) { int n = minHeap->size - 1; int i; for (i = (n - 1) / 2; i >= 0; --i) minHeapify(minHeap, i); } // 判断是否是叶子节点 int isLeaf(HuffmanNode* root) { return !(root->left) && !(root->right); } // 创建并构建最小 MinHeap* createAndBuildMinHeap(char data[], float freq[], int size) { 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; } // 构建哈夫曼 HuffmanNode* buildHuffmanTree(char data[], float 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); top->left = left; top->right = right; insertMinHeap(minHeap, top); } return extractMin(minHeap); } // 打印哈夫曼编码 void printCodes(HuffmanNode* 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[], float freq[], int size) { HuffmanNode* root = buildHuffmanTree(data, freq, size); int arr[MAX_CODE_LENGTH], top = 0; printCodes(root, arr, top); } int main() { char data[] = {'!', '@', '#', '$', '%', '^', '&', '*'}; float freq[] = {0.07, 0.19, 0.02, 0.06, 0.32, 0.03, 0.21, 0.10}; int size = sizeof(data) / sizeof(data[0]); HuffmanCodes(data, freq, size); return 0; } 将这段代码简化一下
最新发布
10-19
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值