哈夫曼

来源:互联网 发布:vb.net 做app开发 编辑:程序博客网 时间:2024/05/02 19:02

#include<iostream.h>
#include<string.h>
#include<iomanip.h>
#include<fstream.h>
#include<stdlib.h>
const maxleaf=30;
const maxnode=maxleaf*2-1;
typedef struct              //定义一个哈夫曼树的结构
{
 char ch;
 int weight;
 int parent;
 int lchild;
 int rchild;
}HNodeType;
HNodeType hftree[maxnode+1];//定义一个哈夫曼树结构的数组
typedef struct              //定义一个编码的结构
{
 int bit[maxleaf+1];
 int start;
}codetype;
codetype Huffcode[maxleaf];//定义一个编码的结构数组
void creathuffmantree(int n);//创建哈夫曼树
void huffcode(int n);      //编码
void trancode(int n);      // 译码
void printtree(int n);     //打印哈夫曼树并输出屏幕中
int n;
void main()
{

 int choice;
 while(1)
 {
  cout<<"                            ★哈夫曼树的编码和译码★\n";
  cout<<"请选择: "<<endl;
  cout<<"1:创建哈夫曼树\n";
  cout<<"2:编码\n";
  cout<<"3:译码\n";
  cout<<"4:打印哈夫曼树\n";
  cout<<"5:退出\n";
  cin>>choice;
  switch(choice)
  {
  case 1:
   {  
    cout<<"输入叶子结点数n:";
    cin>>n;
    cout<<""""<<endl;

    creathuffmantree(n);
   }break;
  case 2: huffcode(n);break;
  case 3: trancode(n);break;
  case 4: printtree(n);break;
  case 5: return;
  }
 }
}
void creathuffmantree(int n)
{
 int i,j,x1,x2,m1,m2,c,p;
 codetype cd;
 for(i=0;i<maxleaf;i++)       
 {
  hftree[i].parent=-1;
  hftree[i].lchild=-1;
  hftree[i].rchild=-1;
  hftree[i].weight=-1;
 }
 cout<<"请输入字符和权值:\n"<<endl;
 for(i=0;i<n;i++)                    //从键盘输入字符和权值
 {
  cout<<"输入第"<<i+1<<"个字符和权值:  ";
  cin>>hftree[i].ch;        
  cin>>hftree[i].weight;
 }
 for(i=0;i<n-1;i++)                 //构造哈夫曼树
 {
  m1=m2=10000;
  x1=x2=0;
  for(j=0;j<n+i;j++)
  {
   if(hftree[j].parent==-1&&hftree[j].weight<m1)
   {
    m2=m1;
    x2=x1;
    m1=hftree[j].weight;
    x1=j;
   }
   else
    if(hftree[j].parent==-1&&hftree[j].weight<m2)
    {
     m2=hftree[j].weight;
     x2=j;
    }
  }
    hftree[x1].parent=n+i;
    hftree[x2].parent=n+i;
    hftree[n+i].weight=hftree[x1].weight+hftree[x2].weight;
    hftree[n+i].lchild=x1;
    hftree[n+i].rchild=x2;
 }
 for(i=0;i<n;i++)
 {
  cd.start=n-1;
  c=i;
  p=hftree[c].parent;
  while(p!=-1)
  {
   if(hftree[p].lchild==c)
    cd.bit[cd.start]=0;
   else cd.bit[cd.start]=1;
         cd.start--;
   c=p;
   p=hftree[c].parent;
  }
  for(j=cd.start+1;j<n;j++)
   Huffcode[i].bit[j]=cd.bit[j];
  Huffcode[i].start=cd.start;
 }
 for(i=0;i<n;i++)
 {
  cout<<hftree[i].ch<<"的编码为:  ";
  for(j=Huffcode[i].start+1;j<n;j++)
   cout<<Huffcode[i].bit[j];
  cout<<endl;
 }
}
void huffcode(int n)  //编码
{

 ofstream file1("e:\\hftreecode.txt",ios::out);
 char ch;
 int q=0;
 int j;
    cout<<"请输入要编码的字符串(按@)结束"<<endl;
 cin>>ch;     //对字符串进行编码
 while(q<n&&ch!='@')
 {
  while(hftree[q].ch!=ch)
      q++;
  for(j=Huffcode[q].start+1;j<n;j++)
  {
   cout<<Huffcode[q].bit[j];
      file1<<Huffcode[q].bit[j];
  }
  q=0;
  cin>>ch;
 }
 file1.close();
  cout<<endl;
}
void trancode(int n)//译码
{
    char c;
 int m1=0,m2=0;
 ifstream file1("e:\\hftreecode.txt",ios::in);
 while(file1.get(c)!='\0')
  m1++;
 file1.close();
 if(m1==0)
 {
  cout<<"请先编码!!"<<endl;
  return;
 }
 ifstream file2("e:\\hftreecode.txt",ios::in);
 char *cc=new char[m1+1];
 while(file2.get(c)!='\0')
 {
  cc[m2]=c;
  m2++;
 }
 cc[m2]='\0';
 int i,j=0;
 i=2*n-2;
 while(cc[j]!='\0')
 {
  if(cc[j]=='0')
   i=hftree[i].lchild;
  else
   i=hftree[i].rchild;
  if(hftree[i].lchild==-1)
  {
   cout<<hftree[i].ch;
   i=2*n-2;
  }
  j++;
 }
 file2.close();
 
}
void printtree(int n)//打印哈夫曼树
{
 int i;
 ofstream file("e:\\printhuffman.txt",ios::out);
 cout<<"字符"<<setw(8)<<"权值"<<setw(8)<<"左孩子"<<setw(8)<<"右孩子"<<setw(8)<<"双亲"<<endl;
 file<<"字符"<<setw(8)<<"权值"<<setw(8)<<"左孩子"<<setw(8)<<"右孩子"<<setw(8)<<"双亲"<<endl;
    for(i=0;i<2*n-1;i++)
 {
  cout<<hftree[i].ch<<setw(8)<<hftree[i].weight<<setw(8)<<hftree[i].lchild<<setw(8)<<hftree[i].rchild<<setw(8)<<hftree[i].parent<<endl;
     file<<hftree[i].ch<<setw(8)<<hftree[i].weight<<setw(8)<<hftree[i].lchild<<setw(8)<<hftree[i].rchild<<setw(8)<<hftree[i].parent<<endl;
 }
 cout<<endl;
 file.close();
}

 

 

原创粉丝点击