Advertisement
Tiger0915

Huffman

Feb 24th, 2013
150
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.98 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. //#include "huffman.h"
  5.  
  6. #define DEBUG 0
  7.  
  8. typedef int data_t;
  9. typedef int bst_key_t;
  10.  
  11. typedef struct bin_node_t {
  12.     data_t data;
  13.     bst_key_t key;
  14.     struct bin_node *left;
  15.     struct bin_node *right;
  16. } bin_node;
  17.  
  18. typedef struct bst_tag {
  19.     bin_node *root;
  20.     int tree_size;
  21. } bst;
  22.  
  23.  
  24. //-----------Functions for binary trees
  25.  
  26. // creates a binary tree and returns a pointer to it
  27. bst *bst_construct()
  28. {
  29.     bst *L;
  30.     L = (bst *) malloc(sizeof(bst));
  31.     L->root = NULL;
  32.  
  33.     L->tree_size = 0;
  34.  
  35.     return L;
  36. }
  37.  
  38. // function to tear down binary tree
  39. void bst_destruct(bst *tree)
  40. {
  41.     while(tree->root != NULL)
  42.     {
  43.         bin_node *node;
  44.         node = tree->root;
  45.         while(node->left != NULL && node->right != NULL)
  46.         {
  47.             if(node->left != NULL) node = (bin_node *)node->left;
  48.             if(node->right != NULL) node = (bin_node *)node->right;
  49.         }
  50.         free(node);
  51.         node = NULL;
  52.     }
  53.     free(tree);
  54.     tree = NULL;
  55. }
  56.  
  57.  
  58.  
  59. // function to insert node into tree
  60. int bst_insert(bst *tree, int *chars, int *char_freqs)
  61. {
  62.     bin_node *new;
  63.     bin_node node_array[256];
  64.     int i, j, k;
  65.  
  66.     //if our tree is empty, create new node and set it as root
  67.     /*
  68.     if(tree->root == NULL)
  69.     {
  70.         new = (bin_node *)malloc(sizeof(bin_node));
  71.         new->right = NULL;
  72.         new->left = NULL;
  73.         new->key = char_frequency;
  74.         new->data = character;
  75.  
  76.         tree->root = new;
  77.         tree->size++;
  78.  
  79.         return 1;
  80.     }
  81.     */
  82.  
  83.     // create a node out ot every char[] index
  84.     for(i=0;i<256;i++)
  85.     {
  86.         node_array[i].key = char_freqs[i];
  87.         node_array[i].data = chars[i];
  88.         node_array[i].left = node_array[i].right = NULL;
  89.     }
  90.  
  91.     // loop through every index of the array, sorting as we go through
  92.     for(i=0;i<256;i++)
  93.     {
  94.         // if frequency is 0, don't add that node to the tree
  95.         if(node_array[i].key == 0) continue;
  96.  
  97.         // combine the first two nodes of array    
  98.         new = (bin_node *)malloc(sizeof(bin_node));
  99.         new->right = &node_array[i+1];
  100.         new->left = &node_array[i];
  101.         new->key = node_array[i].key + node_array[i+1].key;
  102.         new->data = -1;
  103.         // find the point that the next key is not equal to or less
  104.         // than the current key, save that index in j
  105.         j = i+1;
  106.         while(new->key <= node_array[j+1]->key)
  107.             j++;
  108.  
  109.         // shift every element of array from j down to zero down
  110.         // by one index
  111.         for(k=0;k<j;k++)
  112.             node_array[k] = node_array[k+1];
  113.            
  114.         // put our new node in the slot we just opened up by shifting
  115.         node_array[j] = new;
  116.  
  117.        
  118.     }
  119. }
  120.  
  121.  
  122.  
  123.  
  124.  
  125.  
  126.  
  127.  
  128. //-----------END Functions for binary trees
  129.  
  130.  
  131.  
  132.  
  133. // function prints off the contents of the frequency array
  134. void printUnsortedFreq(int *freq)
  135. {
  136.     int i;
  137.     printf("\nFREQUENCIES:\n");
  138.     for(i=0;i<256;i++)
  139.     {
  140.         printf("Character %d occurs %d times\n", i, freq[i]);
  141.     }
  142.     printf("END FREQUENCIES\n\n");
  143. }
  144.  
  145. // function to print of sorted frequency array
  146. void printSortedFreq(int *freq, int *chars)
  147. {
  148.     int i;
  149.     printf("\nSORTED FREQUENCIES:\n");
  150.     for(i=0;i<256;i++)
  151.     {
  152.         printf("Character %c occurs %d times\n",chars[i],freq[i]);
  153.     }
  154. }
  155.  
  156. // function to find the max value of an array
  157. // used for sorting the frequencies of characters
  158. // from largest to smallest
  159. int findMax(int *freq)
  160. {
  161.     int max = 0;
  162.     int i;
  163.     for(i=0;i<256;i++)
  164.     {
  165.         if(freq[i] > max)
  166.             max = i;
  167.     }
  168.     return max;
  169. }
  170.  
  171. // function to find the min value of an array
  172. // used for sorting the frequencies of characters
  173. // from smallest to largest
  174. int findMin(int *freq)
  175. {
  176.     int min = 256;
  177.     int i;
  178.     for(i=0;i<256;i++)
  179.     {
  180.         if(freq[i] < min)
  181.             min = i;
  182.     }
  183.     return min;
  184. }
  185.  
  186. int main(int argc, char *argv[])
  187. {
  188.     FILE *fptInput, *fptOutput;
  189.     int i;
  190.     int freq[256];          // freq is an array that holds the
  191.                             // frequencies of the 256 different possible values
  192.     int sortedFreq[256];    // array to hold the sorted list of frequencies
  193.     int sortedChars[256];   // array to hold the sorted characters themselves,
  194.     int newSortedFreq[256];
  195.     int newSortedChars[256];
  196.                             // from most common to least common
  197.     char currentChar;       // holds the most recently read character from
  198.                             // the input file
  199.     int max;                // placeholder for return of findMax()
  200.  
  201.     // make sure correct command line arguments
  202.     if(argc != 3)
  203.     {
  204.         printf("Error, not enough command line arguments.\n");
  205.         printf("Usage: ./huffman [-c or -d] [filename]\n");
  206.         exit(0);
  207.     }
  208.  
  209.     // open input file from command line and check for correctness
  210.     if((fptInput=fopen(argv[2], "rb"))==NULL)
  211.     {
  212.         printf("Error opening file %s \n",argv[2]);
  213.         exit(0);
  214.     }
  215.  
  216.     // initialize freq, sortedFreq, and sortedChars
  217.     for(i=0;i<256;i++)
  218.     {
  219.         freq[i] = sortedFreq[i] = sortedChars[i] = 0;
  220.     }
  221.     // printUnsortedFreq(freq);
  222.  
  223.  
  224.  
  225.     // use string compare to see if we're in compress mode
  226.     if(!strcmp(argv[1],"-c"))
  227.     {
  228.         printf("You've selected compress mode.\n");
  229.  
  230.         // while there are still bytes to be read, read in a byte,
  231.         // and increment the frequency of that byte
  232.         while(fread(&currentChar, 1, 1, fptInput))
  233.         {
  234.             freq[(int)currentChar]++;
  235.             if(DEBUG) printf("Character %c has a value %d and occurs %d times\n",
  236.                 currentChar, (int)currentChar, freq[(int)currentChar]);
  237.  
  238.         }\
  239.    
  240.         // run through each element of the frequency array, and sort from most
  241.         // common to least common
  242.         for(i=0;i<256;i++)
  243.         {
  244.             max = findMax(freq);
  245.             sortedFreq[i] = freq[max];
  246.             sortedChars[i] = max;
  247.             freq[max] = 0;
  248.         }
  249.  
  250.         // reverse array
  251.         for(i=0;i<256;i++)
  252.         {
  253.  
  254.             newSortedFreq[255-i] = sortedFreq[i];
  255.             newSortedChars[255-i] = sortedChars[i];
  256.         }
  257.  
  258.  
  259.         // printUnsortedFreq(freq);
  260.         // printSortedFreq(newSortedFreq, newSortedChars);
  261.  
  262.     // use string compare to see if we're in decompress mode
  263.     } else if(!strcmp(argv[1],"-d"))
  264.     {
  265.         printf("You've selected decompress mode.\n");
  266.  
  267.     // if the second command line argument isn't -c or -d, then there
  268.     // was a usage error
  269.     } else
  270.     {
  271.         printf("Error. Incorrect input flags, must be -c or -d.\n");
  272.         printf("Usage: ./huffman [-c or -d] [filename]\n");
  273.     }
  274.  
  275.     // close files we opened
  276.     fclose(fptInput);
  277. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement