/* ===================================================================*\



  filename: huffman_code.c

  THIS PROGRAM IS DESIGNED TO DETERMINE THE COMPRESSION RATIO
  ACHIEVED WHEN A FILE IS COMPRESSED USING HUFFMAN CODING.

  PROGRAMMER:  RiNN
  INSTRUCTOR:  Dr. Robert Sczech 
  Class:       CS102 S98
  Date:        Monday April 13, 1998 

\*=====================================================================*/

#include                   //iostream Header
#include                     //assert   Header
#include                    //fstream  Header

//Type Declarations

struct listnode{
    char data; 
    listnode* next;
 };
typedef listnode* list;

struct treenode{
    char letter;
    int number;
    list code;
    treenode *left, *right;
 };
typedef treenode* tree;

struct slistnode{
    tree treeptr;
    slistnode* next;
 };
typedef slistnode* slist;

//GLOBAL VARIABLES
 const int MAX = 128;
 int frequency[MAX];
 slist decodelist;
 tree decodetree;
 list encode[MAX];                         //ENCODE TABLE

 void init();                              //initializations
 void insert(slist &s, int i, int j);      //insert into sorted list
 void tinsert(slist &s, tree t);           //insert tree into sorted list
 void printfreqtable();                    //Print table - debugging
 void printdecodelist();                   //Debugging
 void printencodetable();
 void printlist(list l);
 void print(tree t);

//UTILITY FUNCTIONS
 tree slistpop(slist &s);
 int slistlength(slist s);
 int listlength(list s);
 void listappend(list &l, char c);
 void listcopy(list source, list &dest);
 void decodelist2tree();                   //Converts decodelist to tree
 void decode2encode(tree t);               //Create table from decode tree

 
 int main(int argc, char *argv[]){
     init();
     ifstream file(argv[1]);
     if (file){
         char c;
         while(file.get(c)) 
            frequency[c]++;
         file.close();
     }
     else
        cerr << "' " << argv[1] << "' is not a valid filename" << endl;
    for(int i=0; i 0)
           insert(decodelist, i, frequency[i]);
    decodelist2tree();
    decode2encode(decodetree);
    printencodetable();
    double count = 16 * 128;               //count output bits+overhead
    double incount = 0.0;                  //count input bits
    for(i=0; iletter=(char)i;
  t->number=j;
  t->code=NULL;
  t->left=NULL;
  t->right=NULL;
  tinsert(s, t);
 }

 void tinsert(slist &s, tree t){
  if(s == NULL){
   s =new slistnode;  s->treeptr = t;
   s->next = NULL;
  }
  else if(t->number <= s->treeptr->number){
    slist q=new slistnode;
    q->next = s;
    q->treeptr = t;
    s = q;
  }
 else tinsert(s->next, t);
 }

 void printfreqtable(){
  char ch;
  for(int i=0; i0){
     ch=i;
     cout << ch << "     " << frequency[i] << endl;
  }
 }

 void printdecodelist(){
  slist sl=decodelist;
  while(sl !=NULL){
    cout << sl->treeptr->letter << ", " << sl->treeptr->number << endl;
    sl = sl->next;
  }
 }

 void printencodetable(){
  char ch;
  for(int i=0; idata;
    l = l->next;
  }
  cout << endl;
 }

 void print(tree t){
  if(t !=NULL){
   print(t->left);
   cout << t->number << endl;
   print(t->right);
  }
 }

 tree slistpop(slist &s){
  assert(s !=NULL);
  slist sl = s;
  s = s->next;
  tree t = sl->treeptr;
  delete sl;
  return t;
 }

 int slistlength(slist s){
  int count = 0;
  while(s !=NULL){
    count++;
    s = s->next;
  }
  return count;
 }

 int listlength(list s){
  int count = 0;
  while(s !=NULL){
    count++;
    s = s->next;
  }
  return count;
 }

 void listappend(list &l, char c){
  if(l !=NULL)
    listappend(l->next,c);
  else{
    l = new listnode;
    l->data = c;
    l->next = NULL;
  }
 }

 void listcopy(list source, list &dest){
  while(source !=NULL){
    listappend(dest, source->data);
    source = source->next;
  }
 }



 void decodelist2tree(){
  tree x, y, t;
   while(slistlength(decodelist)>1){
     x=slistpop(decodelist);
     y=slistpop(decodelist);
     t=new treenode;
     t->left = x;
     t->right = y;
     t->number = ((t->left->number) + (t->right->number));
     tinsert(decodelist, t);
   }
   decodetree = slistpop(decodelist);
 }

 void decode2encode(tree t){
  if(t !=NULL){
   if ((t->left==NULL)){
       encode[t->letter] = t->code;
   }
   else{
       listcopy(t->code, t->left->code);
       listappend(t->left->code,'0');
       listcopy(t->code, t->right->code);
       listappend(t->right->code, '1');
       decode2encode(t->left);
       decode2encode(t->right);
    }
  }
 }


RiNN
http://www.oocities.org/Tokyo/2790/