Huffman coding and decoding

#include <iostream>
#include 
<algorithm>
#include 
<functional>
#include 
<vector>
#include 
<iomanip>
#include 
<queue>
#include 
<fstream>
using namespace std;

/*******************************************************************
 * Define the tree-node
 ******************************************************************
*/
class Node
{
    
public:
    Node(
char a,int b, Node *l, Node *r):data(a),freq(b)   //Structor1
    {
        left 
= l;
        right 
= r;
    }
    Node(
const Node & n)                                   //Structor2
    {
    data
=n.data;
    freq
=n.freq;
    left
=n.left;
    right
=n.right;
    }
    
bool operator < (const Node &n)const
    {
        
return freq < n.freq;
    }
    
bool operator == (const Node&n)const
    {
        
return data == n.data;
    }

    
char data;
    
int freq;
    Node 
*left;
    Node 
*right;
};

/*******************************************************************
 * Define the Huffman Tree
 ******************************************************************
*/
class HuffTree
{
    
public:
    HuffTree() { root 
= NULL; }                               //Structor
    ~HuffTree();                                              //Destructor
    HuffTree( vector<Node> );                                 //Create Huffman Tree according to the frequency map
    void mkmap ( vector<Node> &node, string content);
    
void buildTree( vector<Node> node );
    
void Struct (char ch, string bits);                       //Create Huffman Tree according to the word-code map
    void code(string filename);                               //read file and code
    void code(Node* node, string s);                          //print word:code
    void code();                                              //create code
    void decode (fstream tree, fstream code);                 //create decode tree from file
    void print();                                             //print the structure of the tree
    void printTree(Node*,int indent);                         //print tree from a certain node
    private:
    Node 
*root;
};


/*******************************************************************
 * Definition of Haffuman Tree
 ******************************************************************
*/
HuffTree::
~HuffTree()
{
    
//TODO
}

void HuffTree::mkmap( vector<Node> &node, string content)        //make word-frequency map
{
    node.clear();
    
for(unsigned int i=0;i<content.length();++i)                 
    {
    Node n(content.at(i),
1,0,0);
    vector
<Node>::iterator result = find( node.begin(), node.end(), n );
    
if(result == node.end())
    {
        node.push_back(n);
    }
    
else
        result
->freq += 1;
    }
}

void HuffTree::code(string filename)
{
    
string content;
    
char ch;
    ifstream readf;
    readf.open(filename.c_str());
    
if(!readf.is_open())
    {
    cout
<<"please check your filename (it consists of the path)"<<endl;
    
return;
    }
    
while(!readf.eof())
    {
    readf.
get(ch);
    content 
+= ch;
    }
    readf.close();
    cout
<<content;
    vector
<Node> node;
    mkmap(node, content);
    buildTree(node);
    code();
}

void HuffTree::code(Node* node, string s)
{
    
if(NULL == node->left && NULL == node->right)
    cout
<<node->data<<':'<<s<<endl;
    
if(NULL != node->left)
    code(node
->left, s+'0');
    
if(NULL != node->right)
    code(node
->right,s+'1');
}

void HuffTree::code()
{
    
string s="";
    code(root,s);
}

HuffTree::HuffTree( vector
<Node> node)
{
    buildTree (node);
}

void HuffTree::buildTree ( vector<Node> node )
{
    Node 
*= NULL;
    Node 
*= NULL;
    vector
<Node>::iterator current;
    
while(!node.empty())
    {
    current 
= min_element(node.begin(),node.end());
    l 
= new Node(*current);
    current 
= node.erase(current);

    current 
= min_element(node.begin(),node.end());
    r 
= new Node(*current);
    current 
= node.erase(current);
    
    root 
= new Node('*', l->freq + r->freq, l, r);
    
if(!node.empty())
        node.push_back( 
*root );
    }
}

void HuffTree::print()
{
    queue 
<Node> q;
    Node tmp(
0,0,0,0);
    q.push(
*root);
    
while(!q.empty())
    {
    tmp 
= q.front();
    q.pop();
    cout
<<tmp.data<<endl;
    
if(NULL != tmp.left)
        q.push( 
*(tmp.left) );
    
if(NULL != tmp.right)
        q.push( 
*(tmp.right) );
    }
}

/*******************************************************************
 * End of definition
 ******************************************************************
*/


/*******************************************************************
 * main function
 * for test
 ******************************************************************
*/
int main()
{
    HuffTree huff;
    
string filename;
    huff.code(
"change.txt");
    cout 
<< "Input filename:";
    cin 
>> filename;
    huff.code(filename);

    
return 0 ;
}
posted @ 2008-11-02 22:52  ..  阅读(634)  评论(0)    收藏  举报