Huffman

Huffman

/*************.h File**************/
#include <string>
#include <iostream>
#include <fstream>

#ifndef HUFFMAN
#define HUFFMAN

class Huffman
{
 private:
  /*** Node structure ***/
  class BinNode
  {
   public:
    char data;
    BinNode * left,
            * right;

    // BinNode constructor
    BinNode(char item)
    : data(item), left(0), right(0)
    { }
  };

  typedef BinNode * BinNodePointer;

 public:
  /*** Function members ***/
  Huffman();
 
 /******************************************************************/
void BuildDecodingTree(ifstream & CodeFile);
 
/ ******************************************************************
void Insert(char ch, string code);

 
/ ******************************************************************/
void Decode(ifstream & in);

 
 ******************************************************************/
void PrintTree(ostream & out, BinNodePointer root, int indent);

 
 /******************************************************************/
void DisplayDecodingTree(ostream & out);

/*** Data members ***/
private:
  BinNodePointer root;
};

//--- Definition of consructor
inline Huffman::Huffman()
{ root = new BinNode('*'); }

#endif
/****************.cpp File*********************/
#include <string>
#include <iostream>
#include <fstream>
#include <iomanip>
using namespace std;

#ifndef HUFFMAN
#define HUFFMAN

class Huffman
{
private:
/*** Node structure ***/
struct BinNode
{
  char data;
  BinNode * left,
          * right;

  // BinNode constructor
  BinNode(char item)
  {
    data = item;
    left = right = 0;
  }
};

typedef BinNode * BinNodePointer;

/*** Function members ***/
public:
/* Constructor
 *  Precondition:  A Huffman object has been declared.
 *  Postcondition: One-node binary tree with root node
 *                 pointed to by root has been created.
 ******************************************************************/
Huffman();

/* Build the Huffman decoding tree.
 *  Receive:       Huffman object containing this function (implicitly)
 *                 fstream in
 *  Input:         Characters and their codes via in.
 *                 Last line of code file must contain *.
 *  Postcondition: Huffman decoding tree has been created with root
 *                 node pointed to by root.
 ******************************************************************/
void BuildDecodingTree(ifstream & CodeFile);

/* Insert a node for a character in Huffman decoding tree.
 *  Receive:       char c and code, a bit string
 *  Postcondition: Node containing c has been inserted into
 *                 Huffman tree with root pointed to by root.
 ******************************************************************/
void Insert(char ch, string code);

/* Read a message (string of bits) from a file and decode it
 * using the huffman decoding tree.
 *  Receive:   Huffman object containing this function (implicitly)
 *             fstream in connected to message file
 *  Input:     Message via in
 *             Last line of message file must contain *.
 *  Output:    Decoded message
 ******************************************************************/
void Decode(ifstream & in);

/* --- A binary tree printer
 * Displays a binary tree recursively.  The tree is displayed
 * "on its side" with each level  indented by a specified value
 * Indent, but with  no arcs sketched in.
 *  Receive: Root of binary tree and integer indent
 *  Output:  Graphical representation of the binary tree
 ******************************************************************/
void PrintTree(ostream & out, BinNodePointer root, int indent);

/* Display the decoding tree
 *  Receive: Huffman object containing this function (implicitly)
 *           ostream out
 *  Output:  The decoding tree via PrintTree()
 ******************************************************************/
void DisplayDecodingTree(ostream & out);

/*** Data members ***/
private:
  BinNodePointer root;
};

//--- Definition of consructor
inline Huffman::Huffman()
{ root = new BinNode('*'); }

//--- Definition of BuildDecodingTree()
void Huffman::BuildDecodingTree(ifstream & in)
{
  char ch;          // a character
  string code;      // its code
  for (;;)
  {
    in >> ch >> code;
    if (ch == '*') return;
    Insert(ch, code);
  }
}

//--- Definition of Insert()
void Huffman::Insert(char ch, string code)
{
  Huffman::BinNodePointer p = root;   // pointer to move down the tree

  for(int i = 0; i < code.length(); i++)
  {
    switch (code[i])
    {
      case '0' :           // descend left
        if (p->left == 0)  // create node along path
          p->left = new Huffman::BinNode('*');
        p = p->left;
        break;

      case '1' :           // descend right
        if (p->right == 0) // create node along path
          p->right = new Huffman::BinNode('*');
        p = p->right;
        break;

      default:
        cout << "*** Illegal character in code ***\n";
        exit(-1);
    }
  }
  p->data = ch;
}

//--- Definition of Decode()
void Huffman::Decode(ifstream & in)
{
  char bit;                  // next message bit
  Huffman::BinNodePointer p; // pointer to trace path in decoding tree

  for(;;)
  {
    p = root;
    while (p->left != 0 || p->right != 0)
    {
      in >> bit;
      if (bit == '*') return;
      cout << bit;
      if (bit == '0')
        p = p->left;
      else if (bit == '1')
        p = p->right;
      else
        cout << "Illegal bit: " << bit << " -- ignored\n";
    }
    cout << "--" << p->data << endl;
  }
}

//--- Definition of PrintTree()
void Huffman::PrintTree(ostream & out, Huffman::BinNodePointer root,
                        int indent)
{
  if (root != 0)
  {
    PrintTree(out, root->right, indent + 8);
    out << setw(indent) << " " << root->data << endl;
    PrintTree(out, root->left, indent + 8);
  }
}

//--- Definition of DisplayDecodingTree()
inline void Huffman::DisplayDecodingTree(ostream & out)
{ PrintTree(out, root, 0); }

#endif
/*******************main.cpp***********************/
//--- Driver Program ---
#include "Huffman"
#include <iostream>
#include <fstream>

int main()
{
  char filename[32];
  cout << "Enter name of code file: ";  cin >> filename;
  ifstream codestream(filename);
  if (!codestream.is_open())
  {
    cout << "Cannot open code file.\n";
    exit(-1);
  }

  Huffman h;
  h.BuildDecodingTree(codestream);
  h.DisplayDecodingTree(cout);
  cout << endl << endl;
 
  cout << "Enter name of message file: ";  cin >> filename;
  ifstream message(filename);
  if (!message.is_open())
  {
    cout << "Cannot open message file.\n";
    exit(-1);
  }
  h.Decode(message);
}


你可能感兴趣的:(Huffman)