哈夫曼編碼譯碼的設(shè)計(jì)與實(shí)現(xiàn)_第1頁
哈夫曼編碼譯碼的設(shè)計(jì)與實(shí)現(xiàn)_第2頁
哈夫曼編碼譯碼的設(shè)計(jì)與實(shí)現(xiàn)_第3頁
哈夫曼編碼譯碼的設(shè)計(jì)與實(shí)現(xiàn)_第4頁
哈夫曼編碼譯碼的設(shè)計(jì)與實(shí)現(xiàn)_第5頁
已閱讀5頁,還剩18頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、1軟件學(xué)院課程設(shè)計(jì)報(bào)告設(shè)計(jì)名稱: 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì) 選題名稱: 哈夫曼編碼/譯碼的設(shè)計(jì)與實(shí)現(xiàn) 姓 名: 學(xué) 號(hào): 專業(yè)班級(jí): 移動(dòng) 一 班 系 (院): 軟件學(xué)院 設(shè)計(jì)時(shí)間: 2014.6.12014.6.4 目 錄一、需求分析-3 二、系統(tǒng)設(shè)計(jì)-33、 程序流程圖-10四、實(shí)現(xiàn)代碼-13五、總結(jié)-23六、參考書目-23數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)報(bào)告 第 22 頁 共 23 頁1、 需求分析哈夫曼編碼是一種應(yīng)用廣泛且非常有效的數(shù)據(jù)壓縮技術(shù),哈夫曼編碼是一種編碼方式,以哈夫曼樹,帶權(quán)路徑長(zhǎng)度最小的二叉樹,經(jīng)常應(yīng)用于數(shù)據(jù)壓縮。哈夫曼編碼使用一張?zhí)厥獾木幋a表將源字符進(jìn)行編碼。這張編碼表的特殊在于,它是根據(jù)每一

2、個(gè)源字符出現(xiàn)的估算概率而建立起來的。哈夫曼編碼的應(yīng)用很廣泛,利用哈夫曼樹求得的用于通信的二進(jìn)制編碼成為哈夫曼編碼,樹中從根到每個(gè)葉子都有一條路徑,對(duì)路徑上的各分支約定:指向左子樹的分支表示“0”碼,指向右子樹的分支表示“1”碼,取每條路徑上的“0”或“1”的序列作為和各個(gè)葉子對(duì)應(yīng)的字符的編碼,這就是哈夫曼編碼。哈夫曼譯碼輸入字符串可以把它編譯成二進(jìn)制代碼。輸入二進(jìn)制代碼時(shí)可以編譯成字符串。2、 系統(tǒng)設(shè)計(jì)構(gòu)造哈夫曼樹時(shí),使用靜態(tài)鏈表作為哈夫曼樹的存儲(chǔ)。在構(gòu)造哈夫曼樹時(shí),設(shè)計(jì)一個(gè)結(jié)構(gòu)體數(shù)組HuffNode保存哈夫曼樹中各結(jié)點(diǎn)的信息,根據(jù)二叉樹的性質(zhì)可知,具有n個(gè)葉子結(jié)點(diǎn)的哈夫曼樹共有2n-1個(gè)結(jié)點(diǎn)

3、,所以數(shù)組HuffNode的大小設(shè)置為2n-1,求哈夫曼編碼時(shí)使用一維結(jié)構(gòu)數(shù)組HuffCode作為哈夫曼編碼信息的存儲(chǔ)。求哈夫曼編碼實(shí)際上就是在已建立的哈夫曼樹中,從葉子結(jié)點(diǎn)開始,沿結(jié)點(diǎn)的雙親鏈域回退到根結(jié)點(diǎn),每回退一步,就走過了哈夫曼的一個(gè)分支,從而得到一位哈夫曼編碼值。由于一個(gè)字符的哈夫曼編碼就是從根結(jié)點(diǎn)到相應(yīng)葉子結(jié)點(diǎn)所經(jīng)過的路徑上各分支所組成的0、1序列,因此先得到的分支代碼為所求編碼的低位碼,后得到的分支代碼為所求的高位碼1、初始化功能模塊此功能模塊的功能為從鍵盤接受字符集大小n,以及n個(gè)字符和n個(gè)權(quán)值。2、建立哈夫曼編碼的功能模塊此模塊功能為使用1中得到的數(shù)據(jù)按照教材中的構(gòu)造哈弗曼的

4、算法構(gòu)造哈弗曼樹,即將HuffNode數(shù)組中的各個(gè)位置的各個(gè)域都填上相關(guān)的值,并將這個(gè)結(jié)構(gòu)體數(shù)組存于文件nodedata.dat中。函數(shù)原型為:void Creat_Haffmantree(int &n)HNodeType *HaffNode=new HNodeType2*n-1;int i,j;int m1,m2,x1,x2;for(i=0;i<2*n-1;i+)HaffNodei.weight=0;HaffNodei.parent=-1;HaffNodei.lchild=-1;HaffNodei.rchild=-1;HaffNodei.inf='0'for(i

5、=0;i<n;i+)cout<<"請(qǐng)輸入字符"<<endl;cin>>HaffNodei.inf;cout<<"請(qǐng)輸入該字符的權(quán)值"<<endl;cin>>HaffNodei.weight;for(i=0;i<n-1;i+)/構(gòu)造哈夫曼樹m1=m2=Maxvalue;x1=x2=0;for(j=0;j<n+i;j+)/選取最小和次小if(HaffNodej.parent=-1&&HaffNodej.weight<m1)m2=m1;x2=x1;m

6、1=HaffNodej.weight;x1=j;elseif(HaffNodej.parent=-1&&HaffNodej.weight<m2)m2=HaffNodej.weight;x2=j;/將找出的最小和次小合并,創(chuàng)造其父母結(jié)點(diǎn)HaffNodex1.parent=n+i;HaffNodex2.parent=n+i;HaffNoden+i.weight=HaffNodex1.weight+HaffNodex2.weight;HaffNoden+i.lchild=x2;HaffNoden+i.rchild=x1;HaffNoden+i.inf=NULL;cout<

7、<"顯示存儲(chǔ)的哈弗曼樹信息:"<<endl; cout<<"權(quán)值左孩子右孩子雙親"<<endl; for(i=0;i<2*n-1;i+) cout<<HaffNodei.inf<<" " cout<<HaffNodei.weight<<" " cout<<HaffNodei.lchild<<" " cout<<HaffNodei.rchild<<&quo

8、t; " cout<<HaffNodei.parent<<endl; /寫入文件fstream outfile1;outfile1.open("E:nodedata.dat",ios:out|ios:trunc|ios:binary);/建立進(jìn)行寫入的文件if(!outfile1) /沒有創(chuàng)建成功則顯示相應(yīng)信息cout<<"nodedata.dat文件不能打開"<<endl;abort();for(i=0;i<2*n-1;i+) /將內(nèi)存中從HaffNodei地址開始的sizeof(Haff

9、Nodei)的內(nèi)容寫入文件中outfile1.write(char*)&HaffNodei,sizeof(HaffNodei);outfile1.close ();/關(guān)閉文件delete HaffNode;3、建立哈弗曼編碼功的功能模塊此模塊功能是從文件nodedata.dat中讀入相關(guān)的字符信息進(jìn)行哈弗曼編碼,然后將結(jié)果存入code.dat中,同時(shí)將字符與0和1代碼串的一一對(duì)應(yīng)關(guān)系顯示到屏幕上。函數(shù)原型為:void HaffCode(int &n)/哈夫曼編碼HNodeType *HaffNode=new HNodeTypeMaxnode;HcodeType *HaffCod

10、e=new HcodeTypeMaxleaf;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);/建立進(jìn)行寫入的文件for(i=0;i<n;i+)cd.start=n-1;c=i;p=HaffNodec.pa

11、rent;while(p!=-1)if(HaffNodep.lchild=c)cd.bitcd.start=0;elsecd.bitcd.start=1;cd.start-;c=p;p=HaffNodec.parent;for(j=cd.start+1;j<n;j+)HaffCodei.bitj=cd.bitj;HaffCodei.start=cd.start;for(i=0;i<n;i+) outfile<<HaffNodei.inf;for(j=HaffCodei.start+1;j<n;j+)outfile<<HaffCodei.bitj; co

12、ut<<"字符信息-編碼信息"<<endl; for(i=0;i<n;i+) cout<<HaffNodei.inf<<"-" for(j=HaffCodei.start+1;j<n;j+) cout<<HaffCodei.bitj; cout<<endl; outfile.close ();cout<<"請(qǐng)輸入要編碼的字符串,基本元素為("for(i=0;i<n;i+)cout<<HaffNodei.inf<<

13、;","cout<<")"<<endl;char inf100;cin>>inf;int f=strlen(inf);fstream outfile1;outfile1.open("E:code.dat",ios:out|ios:binary);/建立進(jìn)行寫入的文件if(!outfile1) cout<<"code.dat文件不能打開!"<<endl; abort(); else cout<<endl; cout<<"字符

14、串編碼后為:" for(int x=0;x<f;x+) for(i=0;i<n;i+) if(infx=HaffNodei.inf) for(j=HaffCodei.start+1;j<n;j+) outfile1.write(char*)&HaffCodei.bitj,sizeof(HaffCodei.bitj); cout<<HaffCodei.bitj; cout<<endl; cout<<"編譯后的代碼串已經(jīng)存入code.dat文件中!"<<endl; cout<<end

15、l; outfile1.close(); delete HaffNode;delete HaffCode;4. 此模塊功能為接收需要譯碼的0、1代碼串,按照3中建立的編碼規(guī)則將其翻譯成字符集中字符所組成的字符串形式,存入文件textfile.dat,同時(shí)將翻譯的結(jié)果在屏幕上打印輸出。接受0、1代碼串有兩種形式,一種是直接輸入,一種是從文件中讀取。函數(shù)原型為:void decode( int &n)/解碼int i;HNodeType *HaffNode=new HNodeType2*n-1;fstream infile1;infile1.open("E:nodedata.da

16、t",ios:in|ios:binary);/讀出哈夫曼樹if(!infile1)cout<<"nodedata.dat文件不能打開"<<endl;abort();for(i=0;i<2*n-1;i+)infile1.read(char*)&HaffNodei,sizeof(HNodeType);infile1.close(); int tempcode100;int num=0;for(i=0;i<100;i+)tempcodei=-1;HcodeType *Code=new HcodeTypen;cout<&l

17、t;"請(qǐng)選擇要做的操作:"<<endl;cout<<"輸入串解碼,請(qǐng)按4"<<endl;cout<<"從文件中解碼,請(qǐng)按5"<<endl;int q;cin>>q;while(q>5|q<4)cout<<"輸入錯(cuò)誤請(qǐng)重新輸入"cin>>q;switch(q)case 4:cout<<"請(qǐng)輸入要解碼的0,1串(按其他鍵結(jié)束輸入):"<<endl;i=0;cin>

18、>tempcodei;while(tempcodei=0|tempcodei=1)i+;num=i;cin>>tempcodei;cout<<"輸入的編碼為:"for(i=0;i<num;i+)cout<<tempcodei;cout<<endl;int m=2*n-2;i=0;cout<<"譯碼后為:"<<endl; fstream outfile; outfile.open("E:textfile.txt",ios:out); if(!outfil

19、e) cout<<"textfile.txt文件不能打開!"<<endl; abort(); while(i<num)/ 小于字符串的長(zhǎng)度 while(HaffNodem.lchild!=-1&&HaffNodem.rchild!=-1) if(tempcodei=0)m=HaffNodem.lchild;i+;else if(tempcodei=1)m=HaffNodem.rchild;i+; cout<<HaffNodem.inf;outfile<<HaffNodem.inf;m=2*n-2; cou

20、t<<endl; outfile.close(); cout<<"譯碼后的結(jié)果已經(jīng)存入textfile.txt中!"<<endl; delete HaffNode; break;case 5:fstream infile2;/讀編碼infile2.open("E:code.dat",ios:in|ios:binary);while(!infile2.eof()infile2.read(char*)&tempcodenum,sizeof(tempcodenum);num+;infile2.close();num-

21、;cout<<"從文件中讀出的編碼為"<<endl;for(i=0;i<num;i+)cout<<tempcodei; 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文件

22、不能打開!"<<endl; abort(); while(i<num)/ 小于字符串的長(zhǎng)度 while(HaffNodem.lchild!=-1&&HaffNodem.rchild!=-1) if(tempcodei=0)m=HaffNodem.lchild;i+;else if(tempcodei=1)m=HaffNodem.rchild;i+; cout<<HaffNodem.inf;outfile<<HaffNodem.inf;m=2*n-2; cout<<endl; outfile.close(); cou

23、t<<"譯碼后的結(jié)果已經(jīng)存入textfile.txt中!"<<endl; delete HaffNode; break; 3、 程序流程圖1. 系統(tǒng)結(jié)構(gòu)圖 哈夫曼編碼譯碼器 退出 譯碼 編碼 建樹2. 各部分功能圖建樹: 開始 初始化哈夫曼鏈表且有2n-1個(gè)節(jié)點(diǎn) i=1i<n<<p->weight=countip=p->next for(i=n;i<2*n-1;i+) 結(jié)束編碼:開始 將字符存入哈夫曼編碼結(jié)構(gòu)體數(shù)組的字符單元中if(q=q->Parent->LChild)HCi.code-HCi.sta

24、rt=1HCi.code-HCi.start=0 p=p->nexti=n時(shí) 結(jié)束譯碼: 開始Root指向根節(jié)點(diǎn) P!=rootp=p->RChildcodei=0 p=p->LChildp->LChild=NULL&&p->RChild=NULLsk+=strj p=root 結(jié)束4、 實(shí)現(xiàn)代碼/#include "stdafx.h"#include<iostream>#include<fstream>#include<string.h>#include<stdlib.h>usi

25、ng namespace std;#define MaxBit 10#define Maxvalue 100#define Maxleaf 100#define Maxnode Maxleaf*2-1typedef struct int weight;int parent;int lchild;int rchild;char inf;HNodeType;struct HcodeTypeint bitMaxBit;int start;void Creat_Haffmantree(int &n)HNodeType *HaffNode=new HNodeType2*n-1;int i,j;i

26、nt m1,m2,x1,x2;for(i=0;i<2*n-1;i+)HaffNodei.weight=0;HaffNodei.parent=-1;HaffNodei.lchild=-1;HaffNodei.rchild=-1;HaffNodei.inf='0'for(i=0;i<n;i+)cout<<"請(qǐng)輸入字符"<<endl;cin>>HaffNodei.inf;cout<<"請(qǐng)輸入該字符的權(quán)值"<<endl;cin>>HaffNodei.weight;

27、for(i=0;i<n-1;i+)/構(gòu)造哈夫曼樹m1=m2=Maxvalue;x1=x2=0;for(j=0;j<n+i;j+)if(HaffNodej.parent=-1&&HaffNodej.weight<m1)m2=m1;x2=x1;m1=HaffNodej.weight;x1=j;elseif(HaffNodej.parent=-1&&HaffNodej.weight<m2)m2=HaffNodej.weight;x2=j;/創(chuàng)造其父母結(jié)點(diǎn)HaffNodex1.parent=n+i;HaffNodex2.parent=n+i;Ha

28、ffNoden+i.weight=HaffNodex1.weight+HaffNodex2.weight;HaffNoden+i.lchild=x2;HaffNoden+i.rchild=x1;HaffNoden+i.inf=NULL;cout<<"顯示存儲(chǔ)的哈弗曼樹信息:"<<endl; cout<<"權(quán)值左孩子右孩子雙親"<<endl; for(i=0;i<2*n-1;i+) cout<<HaffNodei.inf<<" " cout<<Ha

29、ffNodei.weight<<" " cout<<HaffNodei.lchild<<" " cout<<HaffNodei.rchild<<" " cout<<HaffNodei.parent<<endl; /寫入文件fstream outfile1;outfile1.open("E:nodedata.dat",ios:out|ios:trunc|ios:binary);/建立進(jìn)行寫入的文件if(!outfile1) /沒有創(chuàng)建

30、成功則顯示相應(yīng)信息cout<<"nodedata.dat文件不能打開"<<endl;abort();for(i=0;i<2*n-1;i+) /將內(nèi)存中從HaffNodei地址開始的sizeof(HaffNodei)的內(nèi)容寫入文件中outfile1.write(char*)&HaffNodei,sizeof(HaffNodei);outfile1.close ();/關(guān)閉文件delete HaffNode;void HaffCode(int &n)/哈夫曼編碼HNodeType *HaffNode=new HNodeTypeMax

31、node;HcodeType *HaffCode=new HcodeTypeMaxleaf;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);/建立進(jìn)行寫入的文件for(i=0;i<n;i+)cd.start

32、=n-1;c=i;p=HaffNodec.parent;while(p!=-1)if(HaffNodep.lchild=c)cd.bitcd.start=0;elsecd.bitcd.start=1;cd.start-;c=p;p=HaffNodec.parent;for(j=cd.start+1;j<n;j+)HaffCodei.bitj=cd.bitj;HaffCodei.start=cd.start;for(i=0;i<n;i+) outfile<<HaffNodei.inf;for(j=HaffCodei.start+1;j<n;j+)outfile<

33、;<HaffCodei.bitj; cout<<"字符信息-編碼信息"<<endl; for(i=0;i<n;i+) cout<<HaffNodei.inf<<"-" for(j=HaffCodei.start+1;j<n;j+) cout<<HaffCodei.bitj; cout<<endl; outfile.close ();cout<<"請(qǐng)輸入要編碼的字符串,基本元素為("for(i=0;i<n;i+)cout<&

34、lt;HaffNodei.inf<<","cout<<")"<<endl;char inf100;cin>>inf;int f=strlen(inf);fstream outfile1;outfile1.open("E:code.dat",ios:out|ios:binary);/建立進(jìn)行寫入的文件if(!outfile1) cout<<"code.dat文件不能打開!"<<endl; abort(); else cout<<end

35、l; cout<<"字符串編碼后為:" for(int x=0;x<f;x+) for(i=0;i<n;i+) if(infx=HaffNodei.inf) for(j=HaffCodei.start+1;j<n;j+) outfile1.write(char*)&HaffCodei.bitj,sizeof(HaffCodei.bitj); cout<<HaffCodei.bitj; cout<<endl; cout<<"編譯后的代碼串已經(jīng)存入code.dat文件中!"<&l

36、t;endl; cout<<endl; outfile1.close(); delete HaffNode;delete HaffCode;void decode( int &n)/解碼int i;HNodeType *HaffNode=new HNodeType2*n-1;fstream infile1;infile1.open("E:nodedata.dat",ios:in|ios:binary);/讀出哈夫曼樹if(!infile1)cout<<"nodedata.dat文件不能打開"<<endl;abo

37、rt();for(i=0;i<2*n-1;i+)infile1.read(char*)&HaffNodei,sizeof(HNodeType);infile1.close(); int tempcode100;int num=0;for(i=0;i<100;i+)tempcodei=-1;HcodeType *Code=new HcodeTypen;cout<<"請(qǐng)選擇要做的操作:"<<endl;cout<<"輸入串解碼,請(qǐng)按4"<<endl;cout<<"從文件中

38、解碼,請(qǐng)按5"<<endl;int q;cin>>q;while(q>5|q<4)cout<<"輸入錯(cuò)誤請(qǐng)重新輸入"cin>>q;switch(q)case 4:cout<<"請(qǐng)輸入要解碼的0,1串(按其他鍵結(jié)束輸入):"<<endl;i=0;cin>>tempcodei;while(tempcodei=0|tempcodei=1)i+;num=i;cin>>tempcodei;cout<<"輸入的編碼為:"

39、;for(i=0;i<num;i+)cout<<tempcodei;cout<<endl;int m=2*n-2;i=0;cout<<"譯碼后為:"<<endl; fstream outfile; outfile.open("E:textfile.txt",ios:out); if(!outfile) cout<<"textfile.txt文件不能打開!"<<endl; abort(); while(i<num)/ 小于字符串的長(zhǎng)度 while(Haf

40、fNodem.lchild!=-1&&HaffNodem.rchild!=-1) if(tempcodei=0)m=HaffNodem.lchild;i+;else if(tempcodei=1)m=HaffNodem.rchild;i+; cout<<HaffNodem.inf;outfile<<HaffNodem.inf;m=2*n-2; cout<<endl; outfile.close(); cout<<"譯碼后的結(jié)果已經(jīng)存入textfile.txt中!"<<endl; delete Haf

41、fNode; break;case 5:fstream infile2;/讀編碼infile2.open("E:code.dat",ios:in|ios:binary);while(!infile2.eof()infile2.read(char*)&tempcodenum,sizeof(tempcodenum);num+;infile2.close();num-;cout<<"從文件中讀出的編碼為"<<endl;for(i=0;i<num;i+)cout<<tempcodei; cout<<e

42、ndl; 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)/ 小于字符串的長(zhǎng)度 while(HaffNodem.lchild!=-1&&HaffNodem.rchild!=-1) if(tempcodei=0)m=HaffNodem.lchild;i+;else if(tempcodei=1)m=HaffNodem.rchild;i+; cout<<HaffNodem.inf;outfile<<HaffNodem.inf;m=2*n-2; cout<<endl; outfile.close(); cout<<"譯碼后的結(jié)果已經(jīng)存入t

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論