Mim527

huffan

Jul 21st, 2020
1,006
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.04 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. #define MAX_TREE_HT 50
  5.  
  6. struct MinHNode {
  7.   char item;
  8.   unsigned freq;
  9.   struct MinHNode *left, *right;
  10. };
  11.  
  12. struct MinHeap {
  13.   unsigned size;
  14.   unsigned capacity;
  15.   struct MinHNode **array;
  16. };
  17.  
  18. // Create nodes
  19. struct MinHNode *newNode(char item, unsigned freq) {
  20.   struct MinHNode *temp = (struct MinHNode *)malloc(sizeof(struct MinHNode));
  21.  
  22.   temp->left = temp->right = NULL;
  23.   temp->item = item;
  24.   temp->freq = freq;
  25.  
  26.   return temp;
  27. }
  28.  
  29. // Create min heap
  30. struct MinHeap *createMinH(unsigned capacity) {
  31.   struct MinHeap *minHeap = (struct MinHeap *)malloc(sizeof(struct MinHeap));
  32.  
  33.   minHeap->size = 0;
  34.  
  35.   minHeap->capacity = capacity;
  36.  
  37.   minHeap->array = (struct MinHNode **)malloc(minHeap->capacity * sizeof(struct MinHNode *));
  38.   return minHeap;
  39. }
  40.  
  41. // Function to swap
  42. void swapMinHNode(struct MinHNode **a, struct MinHNode **b) {
  43.   struct MinHNode *t = *a;
  44.   *a = *b;
  45.   *b = t;
  46. }
  47.  
  48. // Heapify
  49. void minHeapify(struct MinHeap *minHeap, int idx) {
  50.   int smallest = idx;
  51.   int left = 2 * idx + 1;
  52.   int right = 2 * idx + 2;
  53.  
  54.   if (left < minHeap->size && minHeap->array[left]->freq < minHeap->array[smallest]->freq)
  55.     smallest = left;
  56.  
  57.   if (right < minHeap->size && minHeap->array[right]->freq < minHeap->array[smallest]->freq)
  58.     smallest = right;
  59.  
  60.   if (smallest != idx) {
  61.     swapMinHNode(&minHeap->array[smallest], &minHeap->array[idx]);
  62.     minHeapify(minHeap, smallest);
  63.   }
  64. }
  65.  
  66. // Check if size if 1
  67. int checkSizeOne(struct MinHeap *minHeap) {
  68.   return (minHeap->size == 1);
  69. }
  70.  
  71. // Extract min
  72. struct MinHNode *extractMin(struct MinHeap *minHeap) {
  73.   struct MinHNode *temp = minHeap->array[0];
  74.   minHeap->array[0] = minHeap->array[minHeap->size - 1];
  75.  
  76.   --minHeap->size;
  77.   minHeapify(minHeap, 0);
  78.  
  79.   return temp;
  80. }
  81.  
  82. // Insertion function
  83. void insertMinHeap(struct MinHeap *minHeap, struct MinHNode *minHeapNode) {
  84.   ++minHeap->size;
  85.   int i = minHeap->size - 1;
  86.  
  87.   while (i && minHeapNode->freq < minHeap->array[(i - 1) / 2]->freq) {
  88.     minHeap->array[i] = minHeap->array[(i - 1) / 2];
  89.     i = (i - 1) / 2;
  90.   }
  91.   minHeap->array[i] = minHeapNode;
  92. }
  93.  
  94. void buildMinHeap(struct MinHeap *minHeap) {
  95.   int n = minHeap->size - 1;
  96.   int i;
  97.  
  98.   for (i = (n - 1) / 2; i >= 0; --i)
  99.     minHeapify(minHeap, i);
  100. }
  101.  
  102. int isLeaf(struct MinHNode *root) {
  103.   return !(root->left) && !(root->right);
  104. }
  105.  
  106. struct MinHeap *createAndBuildMinHeap(char item[], int freq[], int size) {
  107.   struct MinHeap *minHeap = createMinH(size);
  108.  
  109.   for (int i = 0; i < size; ++i)
  110.     minHeap->array[i] = newNode(item[i], freq[i]);
  111.  
  112.   minHeap->size = size;
  113.   buildMinHeap(minHeap);
  114.  
  115.   return minHeap;
  116. }
  117.  
  118. struct MinHNode *buildHuffmanTree(char item[], int freq[], int size) {
  119.   struct MinHNode *left, *right, *top;
  120.   struct MinHeap *minHeap = createAndBuildMinHeap(item, freq, size);
  121.  
  122.   while (!checkSizeOne(minHeap)) {
  123.     left = extractMin(minHeap);
  124.     right = extractMin(minHeap);
  125.  
  126.     top = newNode('$', left->freq + right->freq);
  127.  
  128.     top->left = left;
  129.     top->right = right;
  130.  
  131.     insertMinHeap(minHeap, top);
  132.   }
  133.   return extractMin(minHeap);
  134. }
  135.  
  136. void printHCodes(struct MinHNode *root, int arr[], int top) {
  137.   if (root->left) {
  138.     arr[top] = 0;
  139.     printHCodes(root->left, arr, top + 1);
  140.   }
  141.   if (root->right) {
  142.     arr[top] = 1;
  143.     printHCodes(root->right, arr, top + 1);
  144.   }
  145.   if (isLeaf(root)) {
  146.     printf("  %c   | ", root->item);
  147.     printArray(arr, top);
  148.   }
  149. }
  150.  
  151. // Wrapper function
  152. void HuffmanCodes(char item[], int freq[], int size) {
  153.   struct MinHNode *root = buildHuffmanTree(item, freq, size);
  154.  
  155.   int arr[MAX_TREE_HT], top = 0;
  156.  
  157.   printHCodes(root, arr, top);
  158. }
  159.  
  160. // Print the array
  161. void printArray(int arr[], int n) {
  162.   int i;
  163.   for (i = 0; i < n; ++i)
  164.     printf("%d", arr[i]);
  165.  
  166.   printf("\n");
  167. }
  168.  
  169. int main() {
  170.   char arr[] = {'A', 'B', 'C', 'D'};
  171.   int freq[] = {5, 1, 6, 3};
  172.  
  173.   int size = sizeof(arr) / sizeof(arr[0]);
  174.  
  175.   printf(" Char | Huffman code ");
  176.   printf("\n--------------------\n");
  177.  
  178.   HuffmanCodes(arr, freq, size);
  179. }
Advertisement
Add Comment
Please, Sign In to add comment