狠狠干影院/欧美午夜电影在线观看/高黄文/国产精品一区二区在线观看完整版

數(shù)據(jù)結(jié)構哈夫曼編碼實驗報告畢業(yè)用資料

| 瀏覽次數(shù):

 數(shù)據(jù)結(jié)構實驗報告

 ―― 實驗五

  簡單哈夫曼編/譯碼的設計與實現(xiàn) 本實驗的目的是通過對簡單哈夫曼編/譯碼系統(tǒng)的設計與實現(xiàn)來熟練掌握樹型結(jié)構在實際問題中的應用。此實驗可以作為綜合實驗,階段性實驗時可以選擇其中的幾個功能來設計和實現(xiàn)。

 一、【問題描述】

 利用哈夫曼編碼進行通信可以大大提高信道利用率,縮短信息傳輸時間,降低傳輸成本。但是,這要求在發(fā)送端通過一個編碼系統(tǒng)對待傳數(shù)據(jù)預先編碼,在接收端將傳來的數(shù)據(jù)進行譯碼,此實驗即設計這樣的一個簡單編/碼系統(tǒng)。系統(tǒng)應該具有如下的幾個功能:

 1、接收原始數(shù)據(jù)。

 從終端讀入字符集大小 n,以及 n 個字符和 n 個權值,建立哈夫曼樹,并將它存于文件 nodedata.dat 中。

 2、編碼。

 利用已建好的哈夫曼樹(如不在內(nèi)存,則從文件 nodedata.dat 中讀入),對文件中的正文進行編碼,然后將結(jié)果存入文件 code.dat 中。

 3、譯碼。利用已建好的哈夫曼樹將文件 code.dat 中的代碼進行譯碼,結(jié)果存入文件 textfile.dat 中。

 4、打印編碼規(guī)則。

 即字符與編碼的一一對應關系。

 二、【數(shù)據(jù)結(jié)構設計】

 1、構造哈夫曼樹時使用靜態(tài)鏈表作為哈夫曼樹的存儲。

  在構造哈夫曼樹時,設計一個結(jié)構體數(shù)組 HuffNode 保存哈夫曼樹中各結(jié)點的信息,根據(jù)二叉樹的性質(zhì)可知,具有 n 個葉子結(jié)點的哈夫曼樹共有 2n-1 個結(jié)點,所以數(shù)組 HuffNode 的大小設置為 2n-1,描述結(jié)點的數(shù)據(jù)類型為:

 typedef struct

 {

 int weight;//結(jié)點權值

 int parent;

 int lchild;

 int rchild;

 char inf; }HNodeType;

 2、求哈夫曼編碼時使用一維結(jié)構數(shù)組 HuffCode 作為哈夫曼編碼信息的存儲。

 求哈夫曼編碼,實質(zhì)上就是在已建立的哈夫曼樹中,從葉子結(jié)點開始,沿結(jié)點的雙親鏈域回退到根結(jié)點,沒回退一步,就走過了哈夫曼樹的一個分支,從而得到一位哈夫曼碼值,由于一個字符的哈夫曼編碼是從根結(jié)點到相應葉子結(jié)點所經(jīng)過的路徑上各分支所組成的 0、1 序列,因此先得到的分支代碼為所求編碼的低位碼,后得到的分支代碼位所求編碼的高位碼,所以設計如下數(shù)據(jù)類型:

 #define MAXBIT 10 typedef struct

 {

 int bit[MAXBIT];

 int start; }HcodeType;

  3、文件 nodedata.dat、code.dat 和 textfile.dat。

 三、【功能(函數(shù))設計】

 1、初始化功能模塊。

 此功能模塊的功能為從鍵盤接收字符集大小 n,以及 n 個字符和 n個權值。

 2、建立哈夫曼樹的功能模塊。

 此模塊功能為使用 1 中得到的數(shù)據(jù)按照教材中的構造哈夫曼樹的算法構造哈夫曼樹,即將 HuffNode 數(shù)組中的各個位置的各個域都添上相關的值,并將這個結(jié)構體數(shù)組存于文件 hfmtree.dat 中。

 3、建立哈夫曼編碼的功能模塊。

 此模塊功能為從文件 nodedata.dat 中讀入相關的字符信息進行哈夫曼編碼,然后將結(jié)果存入 code.dat 中,同時將字符與 0、1 代碼串的一一對應關系打印到屏幕上。

 4、譯碼的功能模塊。

 此模塊功能為接收需要譯碼的 0、1 代碼串,按照 3 中建立的編碼規(guī)則將其翻譯成字符集中字符所組成的字符串形式,存入文件

 textfile.dat,同時將翻譯的結(jié)果在屏幕上打印輸出。

 四、【編碼實現(xiàn)】

 #include<iostream.h> #include<fstream.h> #include<string.h> #include<stdlib.h> #define MaxBit 10 #define Maxvalue 100//應該大于權重之和 #define Maxleaf 100 #define Maxnode Maxleaf*2-1 typedef struct

 {

 int weight;

 int parent;

 int lchild;

 int rchild;

 char inf;

 }HNodeType; struct HcodeType {

 int bit[MaxBit];

  int start; };

 void Creat_Haffmantree(int &n) {

 HNodeType *HaffNode=new HNodeType[2*n-1];

 int i,j;

 int m1,m2,x1,x2;

 for(i=0;i<2*n-1;i++)

 {

  HaffNode[i].weight=0;

  HaffNode[i].parent=-1;

  HaffNode[i].lchild=-1;

  HaffNode[i].rchild=-1;

  HaffNode[i].inf="0";

 }

 for(i=0;i<n;i++)

 {

  cout<<"請輸入字符"<<endl;

  cin>>HaffNode[i].inf;

  cout<<"請輸入該字符的權值"<<endl;

  cin>>HaffNode[i].weight;

  }

 for(i=0;i<n-1;i++)//構造哈夫曼樹

 {

  m1=m2=Maxvalue;

  x1=x2=0;

  for(j=0;j<n+i;j++)//選取最小和次小

  {

 if(HaffNode[j].parent==-1&&HaffNode[j].weight<m1)

 {

  m2=m1;

  x2=x1;

  m1=HaffNode[j].weight;

  x1=j;

 }

 else

 {

  if(HaffNode[j].parent==-1&&HaffNode[j].weight<m2)

  {

 m2=HaffNode[j].weight;

 x2=j;

  }

  }

  }

 //將找出的最小和次小合并,創(chuàng)造其父母結(jié)點

  HaffNode[x1].parent=n+i;

  HaffNode[x2].parent=n+i;

  HaffNode[n+i].weight=HaffNode[x1].weight+HaffNode[x2].weight;

  HaffNode[n+i].lchild=x1;

  HaffNode[n+i].rchild=x2;

  HaffNode[n+i].inf=NULL;

 }

  cout<<"顯示存儲的哈弗曼樹信息:"<<endl;

  cout<<"權值 左孩子 右孩子 雙親"<<endl;

  for(i=0;i<2*n-1;i++)

  {

  cout<<HaffNode[i].weight<<"

  ";

 cout<<HaffNode[i].lchild<<"

  ";

 cout<<HaffNode[i].rchild<<"

  ";

  cout<<HaffNode[i].parent<<"

  ";

  cout<<HaffNode[i].inf<<endl;

 }

  //寫入文件

 fstream outfile1;

 outfile1.open("E:\\nodedata.dat",ios::out|ios::trunc|ios::binary);//建立進行寫入的文件

 if(!outfile1) //沒有創(chuàng)建成功則顯示相應信息

 {

  cout<<"nodedata.dat 文件不能打開"<<endl;

  abort();

 }

 for(i=0;i<2*n-1;i++) //將內(nèi)存中從 HaffNode[i]地址開始的sizeof(HaffNode[i])的內(nèi)容寫入文件中

  outfile1.write((char*)&HaffNode[i],sizeof(HaffNode[i]));

 outfile1.close ();//關閉文件

 delete []HaffNode;

  } void HaffCode(int &n)//哈夫曼編碼 {

  HNodeType *HaffNode=new HNodeType[Maxnode];

 HcodeType *HaffCode=new HcodeType[Maxleaf];

  HcodeType cd;

 int i,j,c,p;

 fstream in("E:\\nodedata.dat",ios::in|ios::binary);

 in.read((char*)HaffNode,(2*n-1)*sizeof(HNodeType));

 in.close();

 fstream outfile;

 outfile.open("E:\\codedata.dat",ios::out|ios::binary);//建立進行寫入的文件

 for(i=0;i<n;i++)

 {

  cd.start=n-1;

  c=i;

  p=HaffNode[c].parent;

  while(p!=-1)

  {

 if(HaffNode[p].lchild==c)

  cd.bit[cd.start]=0;

 else

  cd.bit[cd.start]=1;

 cd.start--;

 c=p;

 p=HaffNode[c].parent;

 }

  for(j=cd.start+1;j<n;j++)

 HaffCode[i].bit[j]=cd.bit[j];

  HaffCode[i].start=cd.start;

 }

 for(i=0;i<n;i++)

  {

  outfile<<HaffNode[i].inf;

  for(j=HaffCode[i].start+1;j<n;j++)

 outfile<<HaffCode[i].bit[j];

 }

 cout<<"字符信息--編碼信息"<<endl;

 for(i=0;i<n;i++)

 {

  cout<<HaffNode[i].inf<<"---";

  for(j=HaffCode[i].start+1;j<n;j++)

 cout<<HaffCode[i].bit[j];

  cout<<endl;

 }

 outfile.close ();

 cout<<"請輸入要編碼的字符串,基本元素為(";

  for(i=0;i<n;i++)

  cout<<HaffNode[i].inf<<",";

 cout<<")"<<endl;

 char inf[100];

 cin>>inf;

 int f=strlen(inf);

 fstream outfile1;

 outfile1.open("E:\\code.dat",ios::out|ios::binary);// 建立進行寫入的文件

 if(!outfile1)

 {

  cout<<"code.dat 文件不能打開!"<<endl;

  abort();

 }

 else

 {

 cout<<endl;

 cout<<"字符串編碼后為:";

  for(int x=0;x<f;x++)

 {

 for(i=0;i<n;i++)

 {

  if(inf[x]==HaffNode[i].inf)

 {

 for(j=HaffCode[i].start+1;j<n;j++)

 {

  outfile1.write((char*)&HaffCode[i].bit[j],sizeof(HaffCode[i].bit[j]));

  cout<<HaffCode[i].bit[j];

 }

  }

 }

 }

  }

 cout<<endl;

 cout<<"編譯后的代碼串已經(jīng)存入 code.dat 文件中!"<<endl;

 cout<<endl;

  outfile1.close();

  delete []HaffNode;

 delete []HaffCode;

 } void decode( int &n)//解碼 {

  int i;

 HNodeType *HaffNode=new HNodeType[2*n-1];

 fstream infile1;

 infile1.open("E:\\nodedata.dat",ios::in|ios::binary);//讀出哈夫曼樹

 if(!infile1)

 {

  cout<<"nodedata.dat 文件不能打開"<<endl;

  abort();

 }

  for(i=0;i<2*n-1;i++)

  infile1.read((char*)&HaffNode[i],sizeof(HNodeType));

 infile1.close();

  int tempcode[100];

 int num=0;

 for(i=0;i<100;i++)

  tempcode[i]=-1;

 HcodeType *Code=new HcodeType[n];

 fstream infile2;//讀編碼

 infile2.open("E:\\code.dat",ios::in|ios::binary);

 while(!infile2.eof())

 {

 infile2.read((char*)&tempcode[num],sizeof(tempcode[num]));

  num++;

 }

  infile2.close();

 num--;

 cout<<"從文件中讀出的編碼為"<<endl;

 for(i=0;i<num;i++)

  cout<<tempcode[i];

  cout<<endl;

  int m=2*n-2;

  i=0;

  cout<<endl;

  cout<<"譯碼后為:"<<endl;

  fstream outfile;

  outfile.open("E:\\textfile.txt",ios::out);

  if(!outfile)

  {

  cout<<"textfile.txt 文件不能打開!"<<endl;

 abort();

  }

 while(i<num)// 小于字符串的長度

  {

 while(HaffNode[m].lchild!=-1&&HaffNode[m].rchild!=-1)

  {

 if(tempcode[i]==0)

 {

  m=HaffNode[m].lchild;

  i++;

 }

 else if(tempcode[i]==1)

 {

  m=HaffNode[m].rchild;

  i++;

 }

  }

  cout<<HaffNode[m].inf;

  outfile<<HaffNode[m].inf;

  m=2*n-2;

 }

  cout<<endl;

  outfile.close();

 cout<<"譯碼后的結(jié)果已經(jīng)存入 textfile.txt 中!"<<endl;

 delete []HaffNode;

 }

 int main() {

 int n;

  cout<<"************* 歡 迎 進 入 編 / 譯 碼 系 統(tǒng) !*********************"<<endl;

 int ch1;

  do{

 cout<<"

 1.建樹"<<endl;

  cout<<"

 2:編碼,并顯示字符和對應的編碼"<<endl;

  cout<<"

 3:譯碼"<<endl;

  cout<<"

 0:退出"<<endl;

 cout<<"********************************************************"<<endl;

  cout<<"請選擇(0~3):";

 cin>>ch1;

  while(!(ch1<=3&&ch1>=0)) //輸入不在 0 到 4 之間無效

  {

 cout<<"數(shù)據(jù)輸入錯誤,請重新選擇(0~4):";

 cin>>ch1;

  }

  switch(ch1)

  {

  case

 1:

  {

  cout<<"\t\t\t請輸入編碼個數(shù)"<<endl;//葉子結(jié)點個數(shù)

  cin>>n;

  Creat_Haffmantree(n);

  break;

 }

 case

 2:

 HaffCode(n);

 break;

 case

 3:

 decode(n);

 break;

  }

 }while(ch1!=0);

  return 0; }

  五、【運行與測試】

 1、令葉子結(jié)點個數(shù) n 為 4,權值集合為{1,3,5,7},字符集合為{A,B,C,D},并有如下對應關系,A――1、B――3,C――5,D――7,調(diào)用初始化功能模塊可以正確接收這些數(shù)據(jù)。

 2、調(diào)用建立哈夫曼樹的功能模塊,構造靜態(tài)鏈表 HuffNode 的存儲。

 3、調(diào)用建立哈夫曼編碼的功能模塊,在屏幕上顯示如下對應關系:

 A――111、B――110、C――10、D――0

 4、調(diào)用譯碼的功能模塊,輸入代碼串“111110100”后,屏幕上顯示譯碼結(jié)果:

 111110100 ―――― ABCD

推薦訪問: 數(shù)據(jù)結(jié)構 編碼 實驗

【數(shù)據(jù)結(jié)構哈夫曼編碼實驗報告畢業(yè)用資料】相關推薦

工作總結(jié)最新推薦

NEW