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; }}