C: Huffman Coding
HuffmanCoding.h
/**
* *****************************************************************************
* @file HuffmanCoding.h
* @brief Huffman Coding https://www.programiz.com/dsa/huffman-coding#google_vignette
* IDE VSCODE https://www.geeksforgeeks.org/huffman-coding-greedy-algo-3/
* @author (geovindu,Geovin Du,涂聚文)
* @date 2023-09-27
* @copyright geovindu
* *****************************************************************************
*/
#ifndef HUFFMANCODING_H
#define HUFFMANCODING_H
#include<stdio.h>
#include<stdbool.h>
#define MAX_TREE_HT 50
struct MinHNode {
char item;
unsigned freq;
struct MinHNode *left, *right;
};
struct MinHeap {
unsigned size;
unsigned capacity;
struct MinHNode **array;
};
/**
* @brief Create nodes
*
* @param item
* @param freq
* @return struct MinHNode*
*/
struct MinHNode *newNode(char item, unsigned freq);
/**
* @brief Create a Min H object Create min heap
*
* @param capacity
* @return struct MinHeap*
*/
struct MinHeap *createMinH(unsigned capacity);
/**
* @brief Function to swap
*
* @param a
* @param b
*/
void swapMinHNode(struct MinHNode **a, struct MinHNode **b);
/**
* @brief Heapify
*
* @param minHeap
* @param idx
*/
void minHeapify(struct MinHeap *minHeap, int idx);
/**
* @brief Check if size if 1
*
* @param minHeap
* @return int
*/
int checkSizeOne(struct MinHeap *minHeap);
/**
* @brief Extract min
*
* @param minHeap
* @return struct MinHNode*
*/
struct MinHNode *extractMin(struct MinHeap *minHeap);
/**
* @brief Insertion function
*
* @param minHeap
* @param minHeapNode
*/
void insertMinHeap(struct MinHeap *minHeap, struct MinHNode *minHeapNode);
/**
* @brief
*
* @param minHeap
*/
void buildMinHeap(struct MinHeap *minHeap);
/**
* @brief
*
* @param root
* @return int
*/
int isLeaf(struct MinHNode *root);
/**
* @brief Create a And Build Min Heap object
*
* @param item
* @param freq
* @param size
* @return struct MinHeap*
*/
struct MinHeap *createAndBuildMinHeap(char item[], int freq[], int size);
/**
* @brief
*
* @param item
* @param freq
* @param size
* @return struct MinHNode*
*/
struct MinHNode *buildHuffmanTree(char item[], int freq[], int size);
/**
* @brief
*
* @param root
* @param arr
* @param top
*/
void printHCodes(struct MinHNode *root, int arr[], int top);
/**
* @brief Wrapper function
*
* @param item
* @param freq
* @param size
*/
void HuffmanCodes(char item[], int freq[], int size);
/**
* @brief Print the array
*
* @param arr
* @param n
*/
void HuffmanPrintArray(int arr[], int n);
#endif
HuffmanCoding.c
/**
* *****************************************************************************
* @file HuffmanCoding.c
* @brief Huffman Coding 霍夫曼编码
* @author (geovindu,Geovin Du,涂聚文)
* @date 2023-09-27
* @copyright geovindu
* *****************************************************************************
*/
#include<stdio.h>
#include<stdbool.h>
#include "include/HuffmanCoding.h"
/**
* @brief Create nodes
*
* @param item
* @param freq
* @return struct MinHNode*
*/
struct MinHNode *newNode(char item, unsigned freq) {
struct MinHNode *temp = (struct MinHNode *)malloc(sizeof(struct MinHNode));
temp->left = temp->right = NULL;
temp->item = item;
temp->freq = freq;
return temp;
}
/**
* @brief Create a Min H object Create min heap
*
* @param capacity
* @return struct MinHeap*
*/
struct MinHeap *createMinH(unsigned capacity) {
struct MinHeap *minHeap = (struct MinHeap *)malloc(sizeof(struct MinHeap));
minHeap->size = 0;
minHeap->capacity = capacity;
minHeap->array = (struct MinHNode **)malloc(minHeap->capacity * sizeof(struct MinHNode *));
return minHeap;
}
/**
* @brief Function to swap
*
* @param a
* @param b
*/
void swapMinHNode(struct MinHNode **a, struct MinHNode **b) {
struct MinHNode *t = *a;
*a = *b;
*b = t;
}
/**
* @brief Heapify
*
* @param minHeap
* @param idx
*/
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) {
swapMinHNode(&minHeap->array[smallest], &minHeap->array[idx]);
minHeapify(minHeap, smallest);
}
}
/**
* @brief Check if size if 1
*
* @param minHeap
* @return int
*/
int checkSizeOne(struct MinHeap *minHeap) {
return (minHeap->size == 1);
}
/**
* @brief Extract min
*
* @param minHeap
* @return struct MinHNode*
*/
struct MinHNode *extractMin(struct MinHeap *minHeap) {
struct MinHNode *temp = minHeap->array[0];
minHeap->array[0] = minHeap->array[minHeap->size - 1];
--minHeap->size;
minHeapify(minHeap, 0);
return temp;
}
/**
* @brief Insertion function
*
* @param minHeap
* @param minHeapNode
*/
void insertMinHeap(struct MinHeap *minHeap, struct MinHNode *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;
}
/**
* @brief
*
* @param minHeap
*/
void buildMinHeap(struct MinHeap *minHeap) {
int n = minHeap->size - 1;
int i;
for (i = (n - 1) / 2; i >= 0; --i)
minHeapify(minHeap, i);
}
/**
* @brief
*
* @param root
* @return int
*/
int isLeaf(struct MinHNode *root) {
return !(root->left) && !(root->right);
}
/**
* @brief Create a And Build Min Heap object
*
* @param item
* @param freq
* @param size
* @return struct MinHeap*
*/
struct MinHeap *createAndBuildMinHeap(char item[], int freq[], int size) {
struct MinHeap *minHeap = createMinH(size);
for (int i = 0; i < size; ++i)
minHeap->array[i] = newNode(item[i], freq[i]);
minHeap->size = size;
buildMinHeap(minHeap);
return minHeap;
}
/**
* @brief
*
* @param item
* @param freq
* @param size
* @return struct MinHNode*
*/
struct MinHNode *buildHuffmanTree(char item[], int freq[], int size) {
struct MinHNode *left, *right, *top;
struct MinHeap *minHeap = createAndBuildMinHeap(item, freq, size);
while (!checkSizeOne(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);
}
/**
* @brief
*
* @param root
* @param arr
* @param top
*/
void printHCodes(struct MinHNode *root, int arr[], int top) {
if (root->left) {
arr[top] = 0;
printHCodes(root->left, arr, top + 1);
}
if (root->right) {
arr[top] = 1;
printHCodes(root->right, arr, top + 1);
}
if (isLeaf(root)) {
printf(" %c | ", root->item);
HuffmanPrintArray(arr, top);
}
}
/**
* @brief Wrapper function
*
* @param item
* @param freq
* @param size
*/
void HuffmanCodes(char item[], int freq[], int size) {
struct MinHNode *root = buildHuffmanTree(item, freq, size);
int arr[MAX_TREE_HT], top = 0;
printHCodes(root, arr, top);
}
/**
* @brief Print the array
*
* @param arr
* @param n
*/
void HuffmanPrintArray(int arr[], int n) {
printf("Huffman Coding/n");
int i;
for (i = 0; i < n; ++i)
printf("%d", arr[i]);
printf("\n");
}
调用:
//17. Huffman Coding
char Huffmanarr[] = {'A', 'B', 'C', 'D'};
int freq[] = {5, 1, 6, 3};
int Huffmansize = sizeof(arr) / sizeof(arr[0]);
printf(" 17.霍夫曼编码 Char | Huffman code ");
printf("\n--------------------\n");
HuffmanCodes(Huffmanarr, freq, Huffmansize);
哲学管理(学)人生, 文学艺术生活, 自动(计算机学)物理(学)工作, 生物(学)化学逆境, 历史(学)测绘(学)时间, 经济(学)数学金钱(理财), 心理(学)医学情绪, 诗词美容情感, 美学建筑(学)家园, 解构建构(分析)整合学习, 智商情商(IQ、EQ)运筹(学)生存.---Geovin Du(涂聚文)
浙公网安备 33010602011771号