哈夫曼编码

来源:互联网 发布:北京邮电大学软件排名 编辑:程序博客网 时间:2024/06/05 03:50
/** * 哈夫曼编码 */#include <iostream>#include <fstream>#include <queue>using namespace std;enum NodeType{    NONE = 1,    LEFT_CHILD = 2,    RIGHT_CHILD = 3,};struct Node{    int id;    int weight;    int parent;    NodeType type;};bool operator < (const Node& left,const Node& right){    if (left.weight < right.weight)    {        return true;    }    return false;}bool operator >(const Node& left,const Node& right){    if (right < left)    {        return true;    }    return false;}const int NODE_MAX_NUM = 256;Node nodes[NODE_MAX_NUM];priority_queue<Node,vector<Node>,greater<Node> > Q;char cache = 0;int cache_off = 0;void output_bit(ofstream& ofs,int bit){    if (cache_off > 7)    {        ofs.write(&cache,sizeof(char));        cache_off = 0;        cache = 0;    }    bit = bit ? 1 : 0;    cache |= ((bit & 0xff) >> cache_off);    cache_off ++;}void print_hafuman_code(ofstream &ofs,int off){    if (off == 0)    {        return;    }    print_hafuman_code(ofs,nodes[off].parent);    if (nodes[off].type == LEFT_CHILD)    {        //ofs << "0";        output_bit(ofs,0);    }    else if (nodes[off].type == RIGHT_CHILD)    {        //ofs << "1";        output_bit(ofs,1);    }    return;}int main(){    ifstream fdata("yyxtin.dat",ios::binary);    char ch;    while (fdata.eof() == false)    {        fdata.read(&ch,sizeof(char));        nodes[ch].weight++;    }    for (int i = 0;i < NODE_MAX_NUM;i++)    {        nodes[i].id = i;        nodes[i].type = NONE;        if (nodes[i].weight != 0)        {            Q.push(nodes[i]);            cout << i << ":" << nodes[i].weight << " ";        }    }    cout << endl;    int node_pos = NODE_MAX_NUM / 2;    Node na,nb;    while (Q.size() > 1)    {        na = Q.top();        Q.pop();        nb = Q.top();        Q.pop();        nodes[node_pos].weight = nodes[na.id].weight + nodes[nb.id].weight;        nodes[na.id].parent = node_pos;        nodes[na.id].type = LEFT_CHILD;        nodes[nb.id].parent = node_pos;        nodes[nb.id].type = RIGHT_CHILD;        Q.push(nodes[node_pos]);        node_pos++;    }    /*    for (int i = 0;i < NODE_MAX_NUM / 2;i++)    {        if (nodes[i].weight != 0)        {            cout << (char)i << " ";            print_hafuman_code(cout,i);            cout << endl;        }    }    */    fdata.clear();    fdata.seekg(0,ios::beg);    ofstream fdata_out("yyxtout.dat",ios::app | ios::binary);    while (fdata.eof() == false)    {        fdata.read(&ch,sizeof(char));        print_hafuman_code(fdata_out,ch);    }    fdata_out.close();    return 0;}