huffman编码

来源:互联网 发布:c盘里的windows文件夹 编辑:程序博客网 时间:2024/04/20 04:23
/********************************************--程序描述:数据结构huffman编码的实现--修改日期:2009.5.31--修改人:吴强--修改原因:从前写的程序不够规范--输入要求:输入要编码的.txt文件名********************************************/#include #include #include const int N=26;const int M=2*N-1;const int Max=10000;typedef struct {    char c;    int w;    int lint;    int rint;}NODE;NODE htree[M];//把文件的操作定义成一个类class Cfile{    private:        char *fname;    FILE *fp;    public:    void Openfile();    void sort();    void Closefile()    {    fclose(fp);    delete[] fname;    }};//打开指定文件,并记录各字母(大小写异同)出现次数void Cfile::Openfile(){    fname=new char[50];    cin>> fname;    if ( ( fp=fopen(fname,"r") )==NULL )    {    cout<<"openfile error";    exit(0);    }    while ( !feof(fp) )    {    int k;    char ch=fgetc(fp);//如果不是大小写字母就跳过    if ( (ch< 'a' || ch> 'z') && (ch< 'A' || ch> 'Z') )       {        continue;    }    if (ch>= 'A' && ch<= 'Z')    {        ch+=32;          //小写换成大写    }    int i=0;    int j=N-1;    while ( i<= j )//二分查找,记录各字母权值    {        k=(i+j)/2;        if (ch < htree[k].c)        {            j=k-1;            }        else if (ch > htree[k].c)        {            i=k+1;        }        else          {            htree[k].w+=1;        break;          }    }    }}void Cfile::sort(){    NODE jh;    //冒泡法按权值大小排序    for ( int i=0; i< N; i++ )       {    int k=0;    for ( int j=0; j< N-i+1; j++ )    {        if ( htree[j].w> htree[j+1].w )            {        jh=htree[j];        htree[j]=htree[j+1];        htree[j+1]=jh;        k=1;            }    }    if (!k)    {    break;    }    }}//定义栈class st{    private:        int stack[N];        int top;    public:        st();        void Push(int);        void Pop();        void PutStack(); };st::st(){    for ( int i=0; i< N; i++ )    {        stack[i]=Max;    }    top=-1;}    void st::Push(int x){    stack[++top]=x;}void st::Pop(){    stack[top]=Max;    top--;}void st::PutStack(){    for ( int i=0; i<= top; i++ )    {        cout<< stack[i];    }    cout<< endl;}class huffman{    private:        int l;    public:        huffman()         { l=0;     }    void Create_ht();    void TraverseTree(int);    public:    st code;};void huffman::Create_ht(){    int i=0;    int j=N;    int k=N;    int min_1;    int min_2;    while ( j< M )    {    if ( i< N && htree[i].w<= htree[j].w )    {        min_1=i++;        if ( i< N && htree[i].w<= htree[j].w )    {min_2=i++;    }    else     {min_2=j++;    }    }    else     {        min_1=j++;        if ( i< N && htree[i].w<= htree[j].w )    {            min_2=i++;        }        else             {            min_2=j++;    }    }    htree[k].w=htree[min_1].w+htree[min_2].w;    htree[k].lint=min_1;    htree[k].rint=min_2;    k++;    }} void huffman::TraverseTree(int root){    if ( htree[root].rint!=-1 )    {    code.Push(0);    TraverseTree(htree[root].rint);    code.Pop();    code.Push(1);    TraverseTree(htree[root].lint);    code.Pop();    }    else     {    cout<< l++;    cout<< "   "<< htree[root].c<< "  ";    code.PutStack();        cout<< endl;    }}    void main(){    inline void Init_ht();    Init_ht();    Cfile ff;           ff.Openfile();    ff.sort();    ff.Closefile();    huffman ht;          ht.Create_ht();    cout<< "huffman编码:"<< endl;    ht.TraverseTree(M-1);    cout<< "统计: "<< endl;    for ( int i=0; i< N; i++)    {    cout<< "   "<< htree[i].c<< "   "<< htree[i].w<< "个"<< endl;    }}void Init_ht(){    for ( int i=0; i< N; i++ )    {    htree[i].c='a'+i;    htree[i].w=0;    htree[i].lint=-1;    htree[i].rint=-1;    }    for ( i=N; i< M; i++)    {    htree[i].c='#';    htree[i].w=Max;    htree[i].lint=-1;    htree[i].rint=-1;    }}
原创粉丝点击