设计hafuman 编码器与解码器 C++实现

来源:互联网 发布:粤语听书软件 编辑:程序博客网 时间:2024/06/05 17:38

这是本人在本科阶段的哈弗曼树的代码实现。设计hafuman 编码器与解码器

问题描述:利用哈夫曼编码进行信息通讯可以大大提高信道的利用率,缩短信息传输时间,降低传输成本。但是,这要求在发送端通过一个编码系统对待传输数据预先编码;在接受端将传来的数据进行译码。对于双工信道(即可以双向传输信息的信道),每端都需要一个完整的编/译码系统。试为这样的信息收发站编写一个哈夫曼码的编/译码系统。

基本要求:根据某字符文件统计字符出现频度,构造Huffman 树,编制Huffman编码,并将给定字符文件编码,生成编码文件;再将给定编码文件解码,生成字符文件。(要求按二进制位表示编码)英文文件。用二进制表示编码,生成二进制的编码文件。

 

 

#pragma once#ifndef HUFFMAN_H#define HUFFMAN_H#include <iostream>#include <string>using namespace std;//................  .h文件............class node // 存放字符和字符频率类{public:       intsign;       charch;       intfrequence;       node():frequence(0),sign(0){}       node(charx,int f=0){ch=x;frequence=f;}       node&operator =(const node& n){ch=n.ch;frequence=n.frequence;return *this;}};   //--------------------------------------------------以下是编码类------------------------------------- class hufftree; class huffnode{friend class hufftree;public:       huffnode*next,*leftchild,*rightchild,*parent;       intcode[100]; //.......存放编码....................//       intdata; //..............权值.......................//       charch; //字符//       huffnode(huffnode*pnext=NULL,huffnode*left=NULL,huffnode*right=NULL)       {next=pnext;leftchild=left;rightchild=right;       }//..........数据成员初始花..........//         huffnode(intitem,char a,huffnode *pnext=NULL,huffnode*left=NULL,huffnode*right=NULL)       {data=item;ch=a;next=pnext;leftchild=left;rightchild=right;}};  class hufftree{ public:       nodearray[100]; //.........存放单一字符对象数组.......................//       huffnode*head,*huffroot;       hufftree();       voidInsert(int x,char a); //................插入...................//       voidconnect(huffnode *p); //.....将接点链成单链表........//       huffnode* Min();///......................求频率最小的那个接点       voidFrequence(char line[]);//// 求每个字符的频率       voidSethufftree();//..................造树problem.......................       voidInorder(huffnode *r);//?????????       voidoutput();//-------------------------------------输出函数---       voiddelet(huffnode * p); //...........................断开指针,没有删除----------       voidhuffcode(); // 构造huffman编码       voidoutputcode();//-----------------------------------------------输出编码-----------       voidsortcode(); //............输出编码信息       voidIncode(char cha[]); //信息封装//       voidtranscode(); // 进行译码 };#endif   /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //#include "stdafx.h"#include "huffman.h"#include <iostream>#include <fstream>using namespace std;extern int number;//..........输入字符长度................//extern int a[100]; //....存放输入字符文件编码数组......//extern int maxsize;//........输入字符文件编码长度.............//int count; // 用来记录单一字符的长度 int len(char ch[])// 用来求字符串的长度{       inti(0),num(0);       while(ch[i]!=NULL)       {              num++;              i++;       }       number=num;       returnnum;} hufftree::hufftree() //{huffnode *newnode=new huffnode();head=newnode;head->next=NULL;}  void hufftree::Insert(int x,chara)//===--------------------------插入函数-------------------------{       huffnode*p,*pre;       p=head->next;       if(p==NULL)       {              huffnode*newnode=new huffnode(x,a,NULL,NULL,NULL);              head->next=newnode;              huffroot=newnode;        }       else       {// huffnode(int item,char a,huffnode*pnext=NULL,huffnode*left=NULL,huffnode*right=NULL)              //{data=item;ch=a;next=pnext;leftchild=left;rightchild=right;}              huffnode*newnode=new huffnode(x,a,NULL,NULL,NULL);              while(p)              {                     pre=p;                     p=p->next;              }              pre->next=newnode;              huffroot=newnode;       } }  void hufftree::connect(huffnode *p) // 将哈夫曼树树的叶子结点链成一个单链表(尾插法){       huffnode*t=head,*pre;       while(t)       {              pre=t;              t=t->next;       }       pre->next=p;       p->next=NULL;}  huffnode *hufftree:: Min()///-------------------------------求频率最小的那个接点{       if(head->next==NULL)       {cout<<"文件为空!.."<<endl;       returnNULL;}       else       {               intmin=1000;              huffnode*p=head->next;              huffnode*t;              while(p!=NULL)              {                     if(min>p->data)                     {                            min=p->data;                            t=p;                      }                     p=p->next;              }              delet(t);//.......每次找到最小的接点后断开...........//              returnt;       } }  void hufftree::Frequence(char line[])//// 求每个字符的频率{      char ch[100];for(int x=0;x<len(ch);x++)//.....len(ch)=number..........//{ch[x]=line[x];}int j(0),length(0);int i,k; int size=len(ch); for(k=0;k<size;k++){if(ch[k]!=NULL){array[j].ch=ch[k]; //.......存放单一字符并统计频率.................//for( i=0;i<size;i++){if(ch[i]!=NULL){if(array[j].ch==ch[i]){++array[j].frequence;ch[i]=NULL;                                                                 }}}j++;}}length=j;count=length;//cout<<"length="<<length<<endl;/*for(i=0;i<length;i++){cout<<"The"<<i<<"thchar is "<<array[i].ch<<" The frequence is"<<array[i].frequence<<endl; } */ }  voidhufftree::Sethufftree()//-------------------------------建哈夫曼树--------------------------------------{       huffnode*pt=head->next;       while(pt)       {              huffnode*p=Min();              huffnode*t=Min();              if(t==NULL)//最后一个接点//              {                     Insert((p->data),NULL);              }               else              {                     Insert((p->data+t->data),NULL);              }              huffroot->leftchild=p;              huffroot->rightchild=t;              p->parent=huffroot;              if(t!=NULL)              {                     t->parent=huffroot;              }              pt=head->next->next;              if(pt==NULL)              {                     huffroot->parent=pt;                     head->next=NULL;              }       }} //------------------------哈夫蔓树的中序遍历建立单连表-------------------void hufftree::Inorder(huffnode *r) {       if(r!=NULL)       {              Inorder(r->leftchild);              //cout<<r->data;              if(r->leftchild==NULL&& r->rightchild==NULL)              {                       connect(r);                      //cout<<r->ch;              }              Inorder(r->rightchild);       }} //.....................-输出函数.................................//void hufftree::output(){       huffnode*p=head->next;//头接点       while(p)       {              cout<<p->ch <<" " <<p->data <<endl;              p=p->next;       }}  void hufftree::delet(huffnode * p)//----------------------断开指针-------------{       huffnode*t=head->next,*pre=head;       if(t==NULL){cout<<"All of the elements have been deleted!.."<<endl;exit(1);}       else       {              while(t!=p)              {                     pre=t;                         t=t->next;              }              pre->next=p->next;       }}  void hufftree::huffcode() // 构造huffman编码{       huffnode*p=head->next,*t;        while(p!=NULL)//........遍历单连表(叶子结点).............//       {int i=99;       t=p;//???????       while(t->parent!=NULL)//..........将每个叶子结点的编码放到结点数组.....................//       {              if(t->parent->leftchild==t)              {                     p->code[i]=0;                     i--;              }              else              {                     p->code[i]=1;                     i--;              }              t=t->parent;       }       p=p->next;        } } voidhufftree::outputcode()//----------------------输出编码每个字符的编码--------------------{       huffnode*p=head->next;       intj(0);       while(p)       {              //cout<<"\nThe char " <<p->ch <<" 's huffman codeis ";              for(inti=0;i <100;i++)              {                     if(p->code[i]==0|| p->code[i]==1)                     {                            //cout<<p->code[i];                            a[j]=p->code[i];//.......将开始输入的字符编码放到一个数组..............//                            j++;                     }              }              p=p->next;       }       maxsize=j;//....a[i]字符编码的最大值.....//}   void hufftree::sortcode() //............输出编码信息{ cout<<"编码后信息为:"<<endl;ofstreamoutfile2("file2.txt",ios::binary);if(!outfile2){cout<<"open file2.txterror!"<<endl;exit(1);}  for(int m=0;m<count;m++){       huffnode*p=head->next; //单链表//       while(p)       {              if(array[m].ch==p->ch)              {                     //cout<<"\nThechar "<<p->ch<<" 's huffman code is ";                     for(inti=0;i<100;i++)                     {                            if(p->code[i]==0|| p->code[i]==1)                            {                                                outfile2.write((char*)&p->code[i],sizeof(p->code[i]));                                  }                     }              }              p=p->next;       }}outfile2.close(); ifstreaminfile2("file2.txt",ios::in|ios::binary);if(!infile2){cout<<"open file2.txterror!"<<endl;exit(1);}infile2.read("file2.txt",100 ); while(p){cout<<p->code[i]}infile2.close();*/ cout<<endl;}   void hufftree::Incode(char cha[]) //信息封装//{       intj=0;       //cout<<"NUmber " <<len(cha) <<endl;       /*for(intk=0;k <number;k++) //输出编码//       {       cout<<cha[k];        }*/       for(intm=0;m <number;m++)       {              huffnode*p=head->next;              while(p)              {                      if(cha[m]==p->ch)                     {                            //cout<<"\nThe char " <<p->ch <<" 's huffman codeis ";                            for(inti=0;i <100;i++)                            {                                   if(p->code[i]==0|| p->code[i]==1)                                   {                                          //cout<<p->code[i];                                          a[j]=p->code[i];//........将开始输入的字符文件编码存入数组中.....................//                                          j++;                                   }                            }                     }                     p=p->next;              }       }       maxsize=j; }  void hufftree::transcode() // 进行译码{       ofstreamoutfile3("file3.txt");if(!outfile3){cout <<"open file3.txterror!" <<endl;exit(1);} huffnode *p=huffroot; //哈夫曼树//int i=0;cout <<"译码后信息为: ";while(p){       if(a[i]==0)              p=p->leftchild;       else              p=p->rightchild;        if(p->leftchild==NULL&& p->rightchild==NULL)       {              //cout<<p->ch;              outfile3.put(p->ch);              p=huffroot;//.........返回哈夫树根接点.............//       }         i++;       if(i>=maxsize)              break;}outfile3.close();ifstreaminfile3("file3.txt",ios::in);char c;if(!infile3)cout <<"open error!"<<endl;while(infile3.get(c))cout <<c;infile3.close(); } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////....................main().................//#include "stdafx.h"#include <iostream>#include <fstream>#include <string>#include"huffman.h"using namespace std; int number=0; //存放字符串的长度int a[100]; // 用来存放编码的数组int maxsize=0; // 用来记录编码的长度 extern int count; // 用来记录字符的长度 hufftree list ;       charch[100];     void qidong(){     inti;ifstream infile("file1.txt",ios::in);if(!infile)              {cout<<"open file1.txt error!" <<endl;              exit(1);              }       for(i=0;i<100;i++)       {     infile>>ch[i];if((ch[i]==' ')&&(ch[i+1]==' '))       break;}              infile.close(); }void display(){       for(int i=0;i <count;i++)       {              list.Insert(list.array[i].frequence,list.array[i].ch);//.......将字符链成链表.......//       }}  int main(){    char op;       intflag=1;       while(flag)       {cout<<endl <<"请选择:" <<endl;       cout<<"        菜单            " <<endl;       cout<<"1__启动要编码文件"<<endl;       cout<<"2__编码            " <<endl;       cout<<"3__输出解码后的文件"<<endl;       cout<<"4__退出程序"<<endl;       cout<<endl;       cin>>op;       switch(op)       {       case'1':              cout<<"请启动要编码的文件:"<<endl;                     qidong();//...................调用字符文件..........//              list.Frequence(ch);//.........求每个字符的频率 ........//              display();//list.output();               break;        case'2':              cout<<"对文件进行编码:"<<endl;              list.Sethufftree();//............建哈夫曼树......................//              list.Inorder(list.huffroot);//.........叶子结点链成单链表...............//              //list.output();              list.huffcode();//.........构造huffman编码.......//              list.sortcode();  //.............输出编码............//              break;         case'3':              cout<<"编码后的文件为:"<<endl;              list.Incode(ch);//编译字符文件对应码的信息//              list.transcode();//.......输出译码信息...........//              cout<<endl;              break;                     case'4':              flag=0;              cout<< "程序结束,按任意键退出"<<endl;              break;       default:              cout<<"输入错误,请重新输入!"<<endl;       }       }        system("pause");       return0;}



欢迎 各位拍砖!

原创粉丝点击