Advertisement
Guest User

huffman

a guest
Apr 14th, 2018
16
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.85 KB | None | 0 0
  1. #include <iostream>
  2. #include <fstream>
  3. using namespace std;
  4.  
  5. /*
  6. Node definition for our min heap / huffman tree.
  7. */
  8. struct Node {
  9.     int frequency;
  10.     char data;
  11.     Node* left;
  12.     Node* right;
  13. };
  14.  
  15. typedef struct Node Node;
  16.  
  17. /*
  18. Heap class which is what our huffman tree will create and use.
  19. */
  20. class Heap {
  21. public:
  22.     // Variables.
  23.     int size;
  24.     int capacity;
  25.     struct Node** array;
  26.     // Functions.
  27.     Heap(char _data[], int _freq[], int _size); // Constructor. Creates a new heap of given capacity.
  28.     Node* newNode(char _data, int _freq); // Create a new node for the heap.
  29.     void swapNodes(Node** first, Node** second); // Swap two nodes in place. (Basically changing pointers of them.)
  30.     void heapify(int index); // Time to heapify.
  31.     bool isSizeOne(); // Check size of heap.
  32.     Node* minNode(); // Get minimum node.
  33.     void insertNode(Node* newHeapNode); // Insert a new node.
  34.     void buildHeap(); // Build the heap using heapify.
  35. };
  36.  
  37. /*
  38. The class which makes the huffman tree and it's codes for output.
  39. */
  40. class Huffman {
  41. public:
  42.     // Makes tree and then prints out the code values as needed.
  43.     Huffman(char data[], int freq[], int size);
  44.     // Builds huffman tree.
  45.     Node* buildHuffmanTree(char data[], int freq[], int size);
  46.     // Print out codes (i.e. 10101010101001111, etc.)
  47.     void printCodes(Node* root, int array[], int top);
  48.     bool isLeaf(Node* root); // Check if a node is a leaf node.
  49.     void printArray(int array[], int n);
  50. };
  51.  
  52. // Constructor will create our heap.   
  53. Heap::Heap(char _data[], int _freq[], int _size)
  54. {
  55.     capacity = _size;
  56.     array = (struct Node**)malloc(capacity * sizeof(struct Node*)); // Creates the array for all the nodes needed.
  57.     for (int i = 0; i < _size; i++) {
  58.         array[i] = newNode(_data[i], _freq[i]);
  59.     }
  60.     size = _size;
  61.     buildHeap();
  62. }
  63.  
  64. // Create a new node in memory with given arguments and returns it.
  65. Node* Heap::newNode(char _data, int _freq)
  66. {
  67.     Node* temp = (Node*)malloc(sizeof(Node));
  68.     temp->left = NULL;
  69.     temp->right = NULL;
  70.     temp->data = _data;
  71.     temp->frequency = _freq;
  72.     return temp;
  73. }
  74.  
  75. // Swap two nodes in place. (Basically changing pointers of them.)
  76. void Heap::swapNodes(Node** first, Node** second)
  77. {
  78.     Node* temp = *first;
  79.     *first = *second;
  80.     *second = temp;
  81. }
  82.  
  83. void Heap::heapify(int index)
  84. {
  85.     int smallest = index;
  86.     int right = (2 * index) + 2;
  87.     int left = (2 * index) + 1;
  88.     if ((left < size) && (array[left]->frequency < array[smallest]->frequency)) {
  89.         smallest = left;
  90.     }
  91.     if ((right < size) && (array[right]->frequency < array[smallest]->frequency)) {
  92.         smallest = right;
  93.     }
  94.     if (smallest != index) {
  95.         swapNodes(&array[smallest], &array[index]);
  96.         heapify(smallest);
  97.     }
  98. }
  99.  
  100. bool Heap::isSizeOne()
  101. {
  102.     if (size == 1) {
  103.         return true;
  104.     }
  105.     else {
  106.         return false;
  107.     }
  108. }
  109.  
  110. Node* Heap::minNode()
  111. {
  112.     Node* temp = array[0];
  113.     array[0] = array[size - 1];
  114.     heapify(0);
  115.     return temp;
  116. }
  117.  
  118. void Heap::insertNode(Node* newHeapNode)
  119. {
  120.     int i = size;
  121.     size++;
  122.     while ((i) && (newHeapNode->frequency < (array[(i - 1) / 2])->frequency)) {
  123.         array[i] = array[(i - 1) / 2];
  124.         i = (i - 1) / 2;
  125.     }
  126.     array[i] = newHeapNode;
  127. }
  128.  
  129. void Heap::buildHeap()
  130. {
  131.     int n = size - 1;
  132.     for (int i = (n - 1) / 2; i >= 0; i--) {
  133.         heapify(i);
  134.     }
  135. }
  136.  
  137. bool Huffman::isLeaf(Node* root)
  138. {
  139.     if ((root->left == NULL) && (root->right == NULL)) {
  140.         return true;
  141.     }
  142.     else {
  143.         return false;
  144.     }
  145. }
  146.  
  147. Huffman::Huffman(char data[], int freq[], int size) {
  148.     Node* rootOfTree = buildHuffmanTree(data, freq, size);
  149.     // Print out the tree. (We assume max size is 100 possible.)
  150.     int array[100];
  151.     int top = 0;
  152.     printCodes(rootOfTree, array, top);
  153. }
  154.  
  155. Node* Huffman::buildHuffmanTree(char data[], int freq[], int size)
  156. {
  157.     // Our tree node pointers.
  158.     Node *left, *right, *top;
  159.     // Create the min heap.
  160.     Heap minHeap(data, freq, size);
  161.     // Keeps iterating until size is one of the heap.
  162.     while (!minHeap.isSizeOne()) {
  163.         // Pull out lowest 2 freq nodes.
  164.         left = minHeap.minNode();
  165.         right = minHeap.minNode();
  166.         // Create an internal node.
  167.         // # isn't used in the node since internal.
  168.         top = minHeap.newNode('#', (left->frequency + right->frequency));
  169.         top->left = left;
  170.         top->right = right;
  171.         minHeap.insertNode(top);
  172.     }
  173.     return minHeap.minNode();
  174. }
  175.  
  176. void Huffman::printCodes(Node* root, int array[], int top)
  177. {
  178.     // Recur left, which is assigned a 0.
  179.     if (root->left) {
  180.         array[top] = 0;
  181.         printCodes(root->left, array, (top + 1));
  182.     }
  183.     // Recur right, assigned a 1.
  184.     if (root->right) {
  185.         array[top] = 1;
  186.         printCodes(root->right, array, (top + 1));
  187.     }
  188.     if (isLeaf(root)) {
  189.         printArray(array, top);
  190.     }
  191. }
  192.  
  193. void Huffman::printArray(int array[], int n)
  194. {
  195.     for (int i = 0; i < n; ++i) {
  196.         cout << array[i];
  197.     }
  198. }
  199.  
  200. int main() {
  201.     char array[] = { 'a', 'b', 'c', 'd', 'e', 'f' };
  202.     int freq[] = { 5, 9, 12, 13, 16, 45 };
  203.     int size = sizeof(array) / sizeof(array[0]);
  204.     Huffman tree(array, freq, size);
  205.     return 0;
  206. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement