哈夫曼樹_數(shù)據(jù)結(jié)構(gòu)課程設(shè)計_第1頁
已閱讀1頁,還剩25頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

1、<p>  《 數(shù)據(jù)結(jié)構(gòu) 》課程設(shè)計</p><p>  ——赫夫曼編碼/譯碼器設(shè)計</p><p>  數(shù)據(jù)結(jié)構(gòu)課程設(shè)計實(shí)驗(yàn)報告</p><p><b>  一、題目:</b></p><p>  赫夫曼編碼/譯碼器設(shè)計</p><p><b>  二、目的:</b&g

2、t;</p><p>  1、提高分析問題、解決問題的能力,進(jìn)一步鞏固數(shù)據(jù)結(jié)構(gòu)各種原理與方法。</p><p>  2、熟悉掌握一門計算機(jī)語言,可以進(jìn)行數(shù)據(jù)算法的設(shè)計。</p><p><b>  三、要求</b></p><p><b>  3.1總體要求</b></p><p

3、>  1、要充分認(rèn)識課程設(shè)計對培養(yǎng)自己的重要性,認(rèn)真做好設(shè)計前的各項(xiàng)準(zhǔn)備工作。尤其是對編程軟件的使用有基本的認(rèn)識。</p><p>  2、既要虛心接受老師的指導(dǎo),又要充分發(fā)揮主觀能動性。結(jié)合課題,獨(dú)立思考,努力鉆研,勤于實(shí)踐,勇于創(chuàng)新。</p><p>  3、獨(dú)立按時完成規(guī)定的工作任務(wù),不得弄虛作假,不準(zhǔn)抄襲他人內(nèi)容,否則成績以不及格計。</p><p>

4、  4、在設(shè)計過程中,要嚴(yán)格要求自己,樹立嚴(yán)肅、嚴(yán)密、嚴(yán)謹(jǐn)?shù)目茖W(xué)態(tài)度,必須按時、按質(zhì)、按量完成課程設(shè)計。</p><p><b>  3.2實(shí)施要求</b></p><p>  1、理解赫夫曼編碼/譯碼的確切意義。</p><p>  2、獨(dú)立進(jìn)行方案的制定,系統(tǒng)結(jié)構(gòu)設(shè)計要合理。</p><p>  3、在程序開發(fā)時,則

5、必須清楚主要實(shí)現(xiàn)函數(shù)的目的和作用,需要在程序書寫時說明做適當(dāng)?shù)淖⑨?。在寫課設(shè)報告時,必須要將主要函數(shù)的功能和參數(shù)做詳細(xì)的說明。</p><p>  4、通過多組數(shù)據(jù)來檢測該系統(tǒng)的穩(wěn)定性和正確性。</p><p>  3.3 課程設(shè)計報告的內(nèi)容及要求 </p><p>  在完成課題驗(yàn)收后,學(xué)生應(yīng)在規(guī)定的時間內(nèi)完成課程設(shè)計報告一份(不少于2000字)。</p&g

6、t;<p><b>  一、實(shí)驗(yàn)?zāi)康?lt;/b></p><p>  進(jìn)一步掌握最優(yōu)二叉樹的含義。</p><p>  掌握最優(yōu)二叉樹的結(jié)構(gòu)特征,以及各種存儲結(jié)構(gòu)的特點(diǎn)及使用范圍。</p><p>  熟練掌握哈夫曼樹的建立和哈夫曼編碼方法。</p><p>  掌握用指針類型描述、訪問和處理運(yùn)算。</p

7、><p><b>  二、實(shí)驗(yàn)原理</b></p><p>  哈夫曼(Huffman)編碼屬于碼詞長度可變的編碼類,是哈夫曼在1952年提出的一種編碼方法,即從下到上的編碼方法。同其他碼詞長度可變的編碼一樣,可區(qū)別的不同碼詞的生成是基于不同符號出現(xiàn)的不同概率。生成哈夫曼編碼算法基于一種稱為“編碼樹”(coding tree)的技術(shù)。算法步驟如下:</p>

8、<p> ?。?)初始化,根據(jù)符號概率的大小按由大到小順序?qū)Ψ栠M(jìn)行排序。</p><p>  (2)把概率最小的兩個符號組成一個新符號(節(jié)點(diǎn)),即新符號的概率等于這兩個符號概率之和。</p><p> ?。?)重復(fù)第2步,直到形成一個符號為止(樹),其概率最后等于1。</p><p> ?。?)從編碼樹的根開始回溯到原始的符號,并將每一下分枝賦值為1,上

9、分枝賦值為0。</p><p>  譯碼的過程是分解電文中字符串,從根出發(fā),按字符“0”或“1”確定找做孩子或右孩子,直至葉子節(jié)點(diǎn),便求得該子串相應(yīng)的字符。</p><p><b>  三、實(shí)驗(yàn)內(nèi)容</b></p><p><b>  (一)需求分析</b></p><p>  一個完整的系統(tǒng)應(yīng)具有

10、以下功能:</p><p>  (1) I:初始化。從終端讀入字符集大小n,以及n個字符和n個權(quán)值,建立哈夫曼樹,并將它存于文件hfmTree中。</p><p>  (2) E:編碼。利用已建好的哈夫曼樹,對文件ToBeTran中的正文進(jìn)行編碼,然后將結(jié)果存入文件CodeFile中。</p><p>  (3) D:譯碼。利用已建好的哈夫曼樹將文件CodeFile

11、中的代碼進(jìn)行譯碼,結(jié)果存入文件Textfile中。</p><p>  (4) P:印代碼文件(Print).將文件CodeFile以緊湊格式顯示在終端上,每行50個代碼。同時將此字符形式的編碼文件寫入文件CodePrin中。</p><p>  (5) T:印哈夫曼樹(Treeprinting).將已在內(nèi)存中的哈夫曼樹以直觀的方式(比如樹)顯示在終端上,同時將此字符形式的哈夫曼樹寫入文件

12、TreePrint 中。</p><p><b> ?。ǘ?shí)驗(yàn)步驟</b></p><p>  1.定義結(jié)點(diǎn)結(jié)構(gòu),定義哈夫曼樹結(jié)構(gòu);</p><p>  2.初始化哈夫曼樹,存儲哈夫曼樹信息;</p><p>  3.定義求哈夫曼編碼的函數(shù);</p><p>  4.定義譯哈夫曼編碼的函數(shù);&l

13、t;/p><p><b>  5.寫出主函數(shù)。</b></p><p><b>  6.測試系統(tǒng)。</b></p><p><b> ?。ㄈ└乓O(shè)計</b></p><p><b>  1 設(shè)計思想</b></p><p>  赫夫曼

14、樹用鄰接矩陣作為存儲結(jié)構(gòu),借助靜態(tài)鏈表來實(shí)現(xiàn)遍歷。</p><p><b>  2 函數(shù)間的關(guān)系</b></p><p>  函數(shù)間的關(guān)系如圖所示:</p><p>  圖3.1 函數(shù)間的關(guān)系</p><p>  3 數(shù)據(jù)結(jié)構(gòu)與算法設(shè)計</p><p>  赫夫曼編\譯碼器的主要功能是先建立赫夫曼

15、樹,然后利用建好的赫夫曼樹生成赫夫曼編碼后進(jìn)行譯碼 。</p><p>  在數(shù)據(jù)通信中,經(jīng)常需要將傳送的文字轉(zhuǎn)換成由二進(jìn)制字符0、1組成的二進(jìn)制串,稱之為編碼。構(gòu)造一棵赫夫曼樹,規(guī)定赫夫曼樹中的左分之代表0,右分支代表1,則從根節(jié)點(diǎn)到每個葉子節(jié)點(diǎn)所經(jīng)過的路徑分支組成的0和1的序列便為該節(jié)點(diǎn)對應(yīng)字符的編碼,稱之為赫夫曼編碼。</p><p>  最簡單的二進(jìn)制編碼方式是等長編碼。若采用不等

16、長編碼,讓出現(xiàn)頻率高的字符具有較短的編碼,讓出現(xiàn)頻率低的字符具有較長的編碼,這樣可能縮短傳送電文的總長度。赫夫曼樹課用于構(gòu)造使電文的編碼總長最短的編碼方案。</p><p>  其主要流程圖如圖3.2所示。</p><p>  圖3.2 赫夫曼樹編\譯碼器流程圖</p><p>  4.功能函數(shù)模塊劃分</p><p>  void main

17、()</p><p>  void printhead()</p><p>  void printree(HuffmanTree HT,int w) //打印赫夫曼樹</p><p>  void coprint(HuffmanTree start,HuffmanTree HT)//打印代碼文件</p><p>  void printco

18、de() //打印代碼</p><p>  void decode() //完成譯碼功能</p><p>  void encode() //完成編碼功能</p><p>  void inputcode() </p><p>  void init()</p><p&g

19、t;  void HuffmanCoding(HuffmanTree &HT,HuffmanCode &HC,int *w,int n)</p><p>  void select(HuffmanTree t,int i,int &s1,int &s2)</p><p>  int min(HuffmanTree t,int i)//找兩個最小的權(quán)值<

20、/p><p><b>  (四)詳細(xì)設(shè)計</b></p><p> ?。?)哈夫曼編碼:首先定義函數(shù),找出全部權(quán)值中最小的兩個,然后定義一個變量,使他始終成為最小的那個。再將兩個函數(shù)最為葉子結(jié)點(diǎn),并得到一個父親節(jié)點(diǎn),此父親節(jié)點(diǎn)的權(quán)值為其葉子節(jié)點(diǎn)的權(quán)值之和。并將此父親節(jié)點(diǎn)的權(quán)值與其余權(quán)值進(jìn)行比較,重新選出兩個最小的權(quán)值,再進(jìn)行上述步驟,直到所有權(quán)值形成了一顆二叉樹,而此二叉

21、樹就是我們所說的最優(yōu)二叉樹,即哈夫曼樹。</p><p>  以上為哈夫曼樹的建立過程,下面為哈夫曼編碼的過程,從葉子節(jié)點(diǎn)出發(fā),若此葉子節(jié)點(diǎn)為其父親節(jié)點(diǎn)的左孩子,則將其編碼為0,若為右孩子,則將其編碼為1,然后為其父親節(jié)點(diǎn)編碼,若為祖先的左孩子,則變?yōu)?,為右孩子則為1,依次向上一層進(jìn)行遍歷,直到遍歷到根節(jié)點(diǎn),停止編碼。</p><p>  (2)譯碼:對于已經(jīng)建好的哈夫曼樹,要對其進(jìn)行譯

22、碼,首先從根出發(fā)如果編碼為0,則往左孩子遍歷,如果編碼為1,則往右孩子遍歷,直到遍歷到葉子節(jié)點(diǎn),便求得該子串相應(yīng)的字符。</p><p> ?。?)初始化哈夫曼鏈表:首先輸入結(jié)點(diǎn)個數(shù),再將字符及權(quán)值輸入,調(diào)用編碼函數(shù),得到每個字符編碼并將其輸出。最后將哈夫曼編碼寫入文件。</p><p>  (4)完成編碼功能:打開目錄下文件tobetran.txt,讀取里面的字符,對其進(jìn)行編碼后,將編碼

23、寫入目錄下的codefile.txt中。</p><p>  (5)完成譯碼功能:打開根目錄下codefile.txt文件,讀取里面的編碼,對其中的編碼進(jìn)行譯碼,并將得到的內(nèi)容寫入根目錄下的文件txtfile.txt中。</p><p><b> ?。?)打印編碼</b></p><p><b>  (7)打印哈夫曼樹</b&g

24、t;</p><p><b>  四、實(shí)驗(yàn)結(jié)果</b></p><p>  1.程序運(yùn)行環(huán)境為DOS,執(zhí)行文件為:Huffman2.exe</p><p>  2 . 初始化哈夫曼鏈表(實(shí)驗(yàn)一)</p><p>  在這里,有一個要注意的問題,在程序剛開始運(yùn)行的時候,需要先用“i”命令對哈夫曼樹進(jìn)行初始化。若不進(jìn)行初始化

25、,則表明哈夫曼樹并未建立,這樣就無法進(jìn)行后續(xù)的調(diào)試。</p><p><b>  3.編碼字符</b></p><p><b>  4.編碼</b></p><p><b>  5.譯碼</b></p><p><b>  6.打印編碼</b></p

26、><p><b>  7.打印哈夫曼樹</b></p><p><b> ?。▽?shí)驗(yàn)二)</b></p><p>  1.初始化的內(nèi)容如表所示:</p><p><b>  2.初始化</b></p><p>  3.輸入的字符以及其對應(yīng)的編碼</p&g

27、t;<p><b>  4、譯碼</b></p><p>  5. 文件textfile.txt中內(nèi)容:</p><p>  THIS1PROGRAM1IS1MY1FAVORIT(這里的空格字符定義為1,故出現(xiàn)此譯碼)</p><p><b>  6.打印編碼</b></p><p>

28、<b>  7.打印哈夫曼樹</b></p><p><b>  五、實(shí)驗(yàn)結(jié)果分析</b></p><p>  此算法的時間復(fù)雜度為:O(n),n為哈夫曼樹的結(jié)點(diǎn)個數(shù)。在對哈夫曼編碼/譯碼器算法設(shè)計過程中,主要參考了教材中對哈夫曼編碼/譯碼的算法。在實(shí)現(xiàn)的過程中遇到了一些問題,后來參考網(wǎng)上的一些代碼,進(jìn)行與自己帶嗎的整合,將編碼/譯碼算法完成。而

29、在對編碼以及字符進(jìn)行文件保存、打開時,也遇到了不小的問題,很大一部分來源于對于以前C語言對文件操作的不熟練,所以在解決過程中,參考了一些類似的成功算法實(shí)例。</p><p><b>  六、實(shí)驗(yàn)心得</b></p><p>  對于本次課程設(shè)計,主要是需要掌握哈夫曼樹建立、哈夫曼編碼以及哈夫曼譯碼的算法。并能將其熟練應(yīng)用于編譯碼器的完成。經(jīng)過這次的課程設(shè)計,使我們更加

30、了解了數(shù)據(jù)結(jié)構(gòu),也更深入地了解了哈夫曼編碼與譯碼算法,課程設(shè)計的題目比我們平常的實(shí)驗(yàn)內(nèi)容要難,完成它不僅需要有厚實(shí)的語言基礎(chǔ),而且還要熟練掌握哈夫曼編碼與譯碼的算法,另外對于文件的基本操作也需要熟悉。</p><p>  由于本次課程設(shè)計時間安排得比較遲,所以大部分同學(xué)都在上課之前就把實(shí)驗(yàn)做好了,由于在課外做,碰到許多問題無法請教老師,但是通過上網(wǎng)找尋解決辦法,大部分的錯誤與問題也都能基本解決。</p>

31、;<p><b>  七、主要代碼</b></p><p>  #include <iostream.h></p><p>  #include <iomanip.h></p><p>  #include <string.h></p><p>  #include &l

32、t;malloc.h></p><p>  #include <stdio.h></p><p>  const int UINT_MAX=1000;</p><p>  typedef struct //哈夫曼樹的存儲表示 </p><p><b>  {</b&

33、gt;</p><p>  int weight; //權(quán)值</p><p>  int parent,lchild,rchild; //父節(jié)點(diǎn),左孩子結(jié)點(diǎn),右孩子結(jié)點(diǎn)</p><p>  }HTNode,* HuffmanTree; //動態(tài)分配數(shù)組存儲哈夫曼樹</p><p>  typed

34、ef char **HuffmanCode;//動態(tài)分配數(shù)組存儲哈夫曼編碼表</p><p>  //-----------全局變量-----------------------</p><p>  HuffmanTree HT; //代表赫夫曼樹</p><p>  HuffmanCode HC; /

35、/代表赫夫曼編碼</p><p>  int *w,i,j,n; </p><p><b>  char *z;</b></p><p>  int flag=0; </p><p>  int numb=0;</p><p&

36、gt;  // -----------------求赫夫曼編碼-----------------------</p><p>  void line()//畫分割線的函數(shù)</p><p><b>  {</b></p><p>  cout<<"\n-------------------------------------

37、-------------\n";</p><p><b>  }</b></p><p>  int min(HuffmanTree t,int i)//找兩個最小的權(quán)值</p><p><b>  { </b></p><p>  int j,flag;</p><

38、p>  int k=UINT_MAX; // 取k為不小于可能的值</p><p>  for(j=1;j<=i;j++)</p><p>  if(t[j].weight<k&&t[j].parent==0)</p><p>  k=t[j].weight,flag=j;</p><p>  t[flag]

39、.parent=1;</p><p>  return flag; //返回標(biāo)識符</p><p><b>  }</b></p><p>  //--------------------使s1成為最小權(quán)值----------------------</p><p>  void select(HuffmanTr

40、ee t,int i,int &s1,int &s2)</p><p><b>  { </b></p><p><b>  int j;</b></p><p>  s1=min(t,i);</p><p>  s2=min(t,i);</p><p>  

41、if(s1>s2)// s1為最小的兩個值中序號較小的那個</p><p><b>  {</b></p><p><b>  j=s1;</b></p><p><b>  s1=s2;</b></p><p><b>  s2=j;</b><

42、;/p><p><b>  }</b></p><p><b>  }</b></p><p>  void HuffmanCoding(HuffmanTree &HT,HuffmanCode &HC,int *w,int n)</p><p><b>  {</b>

43、;</p><p>  int m,i,s1,s2,start;</p><p><b>  int c,f;</b></p><p>  HuffmanTree p;</p><p><b>  char *cd;</b></p><p><b>  if(n&l

44、t;=1)</b></p><p><b>  return;</b></p><p>  m=2*n-1;//申請2n-1個內(nèi)存單元</p><p>  HT=(HuffmanTree)malloc((m+1)*sizeof(HTNode)); // 0號單元未用</p><p>  for(p=HT+1,

45、i=1;i<=n;++i,++p,++w)</p><p><b>  {</b></p><p>  p->weight=*w;//賦權(quán)值</p><p>  p->parent=0;</p><p>  p->lchild=0;</p><p>  p->rchi

46、ld=0;</p><p><b>  }</b></p><p>  for(;i<=m;++i,++p)//初始化</p><p>  p->parent=0; </p><p>  for(i=n+1;i<=m;++i) // 建赫夫曼樹</p><p><

47、;b>  { </b></p><p>  select(HT,i-1,s1,s2);//調(diào)用建子樹的函數(shù)</p><p>  HT[s1].parent=HT[s2].parent=i;//i是s1和s2的父節(jié)點(diǎn)</p><p>  HT[i].lchild=s1;</p><p>  HT[i].rchild=s2;//

48、s1和s2是i的兒子節(jié)點(diǎn)</p><p>  HT[i].weight=HT[s1].weight+HT[s2].weight;//i的權(quán)值為s1和s2的和</p><p><b>  }</b></p><p>  HC=(HuffmanCode)malloc((n+1)*sizeof(char*));//分配n個字符編碼的頭指針向量<

49、/p><p>  cd=(char*)malloc(n*sizeof(char)); //分配求編碼的工作空間</p><p>  cd[n-1]='\0'; //編碼結(jié)束符</p><p>  for(i=1;i<=n;i++)//逐個字符求哈夫曼編碼</p><p><b>  {</b></

50、p><p>  start=n-1; //編碼結(jié)束符位置</p><p>  for(c=i,f=HT[i].parent;f!=0;c=f,f=HT[f].parent) // 從葉子到根逆向求編碼</p><p>  if(HT[f].lchild==c)</p><p>  cd[--start]='0';</p>

51、;<p><b>  else</b></p><p>  cd[--start]='1';</p><p>  HC[i]=(char*)malloc((n-start)*sizeof(char));//為第i個字符編碼分配空間</p><p>  strcpy(HC[i],&cd[start]);

52、 //從cd復(fù)制編碼(串)到HC</p><p><b>  }</b></p><p>  free(cd);//釋放工作空間</p><p><b>  }</b></p><p>  //--------------初始化哈夫曼鏈表-------------------------------

53、--</p><p>  void init()</p><p><b>  { </b></p><p><b>  flag=1;</b></p><p><b>  int num;</b></p><p><b>  int nu

54、m2;</b></p><p>  cout<<"下面初始化赫夫曼鏈表"<<endl<<"請輸入結(jié)點(diǎn)的個數(shù)n:";</p><p>  cin>>num;//輸入結(jié)點(diǎn)個數(shù)</p><p><b>  n=num;</b></p>&

55、lt;p>  w=(int*)malloc(n*sizeof(int));//權(quán)值</p><p>  z=(char*)malloc(n*sizeof(char));//字符</p><p>  cout<<"\n請依次輸入"<<n<<"個字符(字符型)\n注意:必須以回車結(jié)束:"<<endl;

56、</p><p>  char temp[2];</p><p>  for(i=0;i<n;i++)//輸入字符</p><p><b>  {</b></p><p>  cout<<"第"<<i+1<<"個字符:"<<en

57、dl;</p><p>  gets(temp);</p><p>  *(z+i)=*temp;</p><p><b>  }</b></p><p><b>  line();</b></p><p>  for(i=0;i<=n-1;i++)//輸出字符<

58、/p><p><b>  {</b></p><p>  cout<<setw(6)<<*(z+i);</p><p><b>  }</b></p><p><b>  line();</b></p><p>  cout<&

59、lt;"\n請依次輸入"<<n<<"個權(quán)值(\n注意:必須以回車結(jié)束):"<<endl;</p><p>  for(i=0;i<=n-1;i++)//輸入權(quán)值</p><p><b>  {</b></p><p>  cout<<endl<&

60、lt;"第"<<i+1<<"個字符的權(quán)值:";</p><p>  cin>>num2;</p><p>  *(w+i)=num2;</p><p><b>  }</b></p><p>  HuffmanCoding(HT,HC,w,n);

61、//調(diào)用哈夫曼編碼</p><p>  //------------------------打印編碼----------------------</p><p>  cout<<"字符對應(yīng)的編碼為:"<<endl;</p><p>  for(i=1;i<=n;i++)//輸出所有編碼</p><

62、p><b>  {</b></p><p>  puts(HC[i]);</p><p><b>  }</b></p><p>  //--------------------------將赫夫曼編碼寫入文件---------</p><p>  cout<<"下面將赫

63、夫曼編碼寫入文件"<<endl;</p><p>  FILE *htmTree;</p><p>  char r[]={' ','\0'}; </p><p>  if((htmTree=fopen("htmTree.txt","w"))==NULL)<

64、;/p><p><b>  {</b></p><p>  cout<<"文件打開失敗"<<endl;</p><p><b>  return;</b></p><p><b>  }</b></p><p> 

65、 fputs(z,htmTree);</p><p>  for(i=0;i<n+1;i++)</p><p><b>  {</b></p><p>  fprintf(htmTree,"%6d",*(w+i));</p><p>  fputs(r,htmTree);</p>

66、<p><b>  }</b></p><p>  for(i=1;i<=n;i++)</p><p><b>  {</b></p><p>  fputs(HC[i],htmTree);</p><p>  fputs(r,htmTree);</p><p&g

67、t;<b>  }</b></p><p>  fclose(htmTree);</p><p>  cout<<"已將字符與對應(yīng)編碼寫入根目錄下文件htmTree.txt中"<<endl<<endl;</p><p><b>  }//init</b></p&

68、gt;<p>  //---------------------獲取字符并寫入文件---------------------------------</p><p>  void inputcode() </p><p><b>  {</b></p><p>  FILE *virttran,*tobetran;</

69、p><p>  char str[100];</p><p>  if((tobetran=fopen("tobetran.txt","w"))==NULL)</p><p><b>  {</b></p><p>  cout<<"不能打開文件"<

70、;<endl;</p><p><b>  return;</b></p><p><b>  }</b></p><p>  cout<<"請輸入你想要編碼的字符"<<endl;</p><p>  gets(str);</p>&l

71、t;p>  fputs(str,tobetran);</p><p>  cout<<"獲取字符成功"<<endl;</p><p>  fclose(tobetran);</p><p><b>  }</b></p><p>  //-----------------

72、-------------------------------------</p><p>  void encode() //完成編碼功能</p><p><b>  {</b></p><p>  cout<<"下面對目錄下文件tobetran.txt中的字符進(jìn)行編碼"<<end

73、l;</p><p>  FILE *tobetran,*codefile;</p><p>  if((tobetran=fopen("tobetran.txt","rb"))==NULL)</p><p><b>  {</b></p><p>  cout<<&q

74、uot;不能打開文件"<<endl;</p><p><b>  }</b></p><p>  if((codefile=fopen("codefile.txt","wb"))==NULL)</p><p><b>  {</b></p><

75、;p>  cout<<"不能打開文件"<<endl;</p><p><b>  }</b></p><p>  char *tran;</p><p><b>  i=99;</b></p><p>  tran=(char*)malloc(100

76、*sizeof(char)); //為tran分配100個字節(jié)</p><p>  while(i==99)</p><p><b>  {</b></p><p>  if(fgets(tran,100,tobetran)==NULL)</p><p><b>  {</b></p>

77、<p>  cout<<"不能打開文件"<<endl;</p><p><b>  break;</b></p><p><b>  }</b></p><p>  for(i=0;*(tran+i)!='\0';i++)</p><

78、;p><b>  {</b></p><p>  for(j=0;j<=n;j++)</p><p><b>  {</b></p><p>  if(*(z+j-1)==*(tran+i))</p><p><b>  {</b></p><p

79、>  fputs(HC[j],codefile);</p><p>  puts(HC[j]);</p><p><b>  if(j>n)</b></p><p><b>  {</b></p><p>  cout<<"字符錯誤,無法編碼!"<&

80、lt;endl;</p><p><b>  break;</b></p><p><b>  }</b></p><p><b>  }</b></p><p><b>  }</b></p><p><b>  }&l

81、t;/b></p><p><b>  }</b></p><p>  cout<<"編碼工作完成"<<endl<<"編碼寫入目錄下的codefile.txt中"<<endl<<endl;</p><p>  fclose(tobetran

82、);</p><p>  fclose(codefile);</p><p>  free(tran);</p><p><b>  }</b></p><p>  //--------------------------------------------------</p><p>  voi

83、d decode() //完成譯碼功能</p><p><b>  {</b></p><p>  cout<<"下面對根目錄下文件codefile.txt中的字符進(jìn)行譯碼"<<endl;</p><p>  FILE *codef,*txtfile;</p><p&g

84、t;  if((txtfile=fopen("Textfile.txt","w"))==NULL)</p><p><b>  {</b></p><p>  cout<<"不能打開文件"<<endl;</p><p><b>  }</b>

85、;</p><p>  if ((codef=fopen("codefile.txt","r"))==NULL)</p><p><b>  {</b></p><p>  cout<<"不能打開文件"<<endl;</p><p>&l

86、t;b>  }</b></p><p>  char *tbdc,*outext,i2;</p><p>  int io=0,i,m;</p><p>  unsigned long length=10000;</p><p>  tbdc=(char*)malloc(length*sizeof(char)); //分配空

87、間</p><p>  fgets(tbdc,length,codef);</p><p>  outext=(char*)malloc(length*sizeof(char)); //分配空間</p><p><b>  m=2*n-1;</b></p><p>  for(i=0;*(tbdc+i)!='\0

88、';i++) //進(jìn)入循環(huán)</p><p><b>  {</b></p><p>  i2=*(tbdc+i);</p><p>  if(HT[m].lchild==0) </p><p><b>  {</b></p><p>  *(outext+io)=*

89、(z+m-1);</p><p><b>  io++;</b></p><p><b>  m=2*n-1;</b></p><p><b>  i--;</b></p><p><b>  }</b></p><p>  els

90、e if(i2=='0') m=HT[m].lchild;</p><p>  else if(i2=='1') m=HT[m].rchild;</p><p><b>  }</b></p><p>  *(outext+io)='\0';</p><p>  fputs

91、(outext,txtfile);</p><p>  cout<<"譯碼完成"<<endl<<"內(nèi)容寫入根目錄下的文件txtfile.txt中"<<endl<<endl;</p><p>  free(tbdc);</p><p>  free(outext);&l

92、t;/p><p>  fclose(txtfile);</p><p>  fclose(codef);</p><p><b>  }</b></p><p>  //---------------------------------------------</p><p>  void print

93、code() //打印代碼</p><p><b>  {</b></p><p>  cout<<"下面打印根目錄下文件CodePrin.txt中編碼字符"<<endl<<"--------------------------------------------------------

94、---------\n";</p><p>  FILE * CodePrin,* codefile;</p><p>  if((CodePrin=fopen("CodePrin.txt","w"))==NULL)</p><p><b>  {</b></p><p>

95、;  cout<<"不能打開文件"<<endl;</p><p><b>  return;</b></p><p><b>  }</b></p><p>  if((codefile=fopen("codefile.txt","r"))

96、==NULL)</p><p><b>  {</b></p><p>  cout<<"不能打開文件"<<endl;</p><p><b>  return;</b></p><p><b>  }</b></p>

97、<p>  char *work3;</p><p>  work3=(char*)malloc(51*sizeof(char));</p><p><b>  do</b></p><p><b>  {</b></p><p>  if(fgets(work3,51,codefile)

98、==NULL)</p><p><b>  {</b></p><p>  cout<<"不能讀取文件"<<endl;</p><p><b>  break;</b></p><p><b>  }</b></p>&

99、lt;p>  fputs(work3,CodePrin);</p><p>  puts(work3);</p><p>  }while(strlen(work3)==50);</p><p>  free(work3);</p><p>  cout<<"打印工作結(jié)束"<<endl<

100、<endl;</p><p>  fclose(CodePrin);</p><p>  fclose(codefile);</p><p><b>  }</b></p><p>  void coprint(HuffmanTree start,HuffmanTree HT)//打印代碼文件</p>

101、<p>  {char t=' ';</p><p>  if(start!=HT)</p><p><b>  {</b></p><p>  FILE * TreePrint;</p><p>  if((TreePrint=fopen("TreePrint.txt",

102、"a"))==NULL)</p><p><b>  {</b></p><p>  cout<<"創(chuàng)建文件失敗"<<endl;</p><p><b>  return;</b></p><p><b>  }

103、</b></p><p>  numb++;//該變量為已被聲明為全局變量</p><p>  coprint(HT+start->rchild,HT);</p><p>  if(start->lchild!=NULL&&start->rchild!=NULL) t='<';</p>

104、<p>  cout<<setw(5*numb)<<start->weight<<t<<endl; </p><p>  fprintf(TreePrint,"%d\n",start->weight);</p><p>  coprint(HT+start->lchild,HT);</

105、p><p><b>  numb--;</b></p><p>  fclose(TreePrint);</p><p><b>  }</b></p><p><b>  }</b></p><p>  void printree(HuffmanTree

106、HT,int w) //打印赫夫曼樹</p><p><b>  {</b></p><p>  HuffmanTree p;</p><p><b>  p=HT+w;</b></p><p>  cout<<"下面打印赫夫曼樹"<<endl; // 輸

107、出"打印赫夫曼樹"語句</p><p>  coprint(p,HT);</p><p>  cout<<"打印工作結(jié)束"<<endl; //輸出"打印工作結(jié)束"</p><p><b>  }</b></p><p>  void pr

108、inthead()</p><p><b>  { </b></p><p>  cout<<"\t數(shù)據(jù)結(jié)構(gòu)\t課程設(shè)計\t09數(shù)媒2班 林真超 E09700203\n";</p><p>  cout<<"\n\t\t"; </p><p

109、>  cout<<"  i.初始化赫夫曼鏈表 w.編碼字符 \n\t\t";</p><p>  cout<<"  e.編 碼   d.譯 碼   \n\t\t";</p><p>  cout<<"   p.打印

110、編碼     t.打印赫夫曼樹    \n\t\t";</p><p>  cout<<"   q.退 出       \n\t\t";</p><p>  if(flag==0)cout<<"\n請先初始化赫夫曼鏈表,輸入'i'\n";&

111、lt;/p><p>  cout<<"請選擇你要進(jìn)行的操作:";</p><p><b>  }</b></p><p><b>  /*2.主程序*/</b></p><p>  void main()</p><p><b>  {&

112、lt;/b></p><p>  char choice;</p><p>  while(choice!='q')</p><p>  { printhead();</p><p>  cin>>choice;</p><p>  switch(choice)</p&

113、gt;<p><b>  {</b></p><p>  case 'i': //按下i則進(jìn)行初始化赫夫曼鏈表,調(diào)用init函數(shù) </p><p>  init(); </p><p><b>  break;</b></p><p>

114、;  case 'w': //按下w編碼字符,調(diào)用inputcode函數(shù)</p><p>  inputcode();</p><p><b>  break;</b></p><p>  case 'e': //按下e編碼,調(diào)用encode函數(shù)</p><p><

115、;b>  encode();</b></p><p><b>  break;</b></p><p>  case 'd': //按下d譯碼,調(diào)用decode函數(shù)</p><p><b>  decode();</b></p><p><b>

116、  break;</b></p><p>  case 'p': //按下p打印編碼,調(diào)用printcode函數(shù)</p><p>  printcode();</p><p><b>  break;</b></p><p>  case 't': //按下

117、t打印赫夫曼樹,調(diào)用printree函數(shù)</p><p>  printree(HT,2*n-1);</p><p><b>  break;</b></p><p>  case 'q': //按下q退出</p><p><b>  break;</b></p&g

118、t;<p><b>  default:</b></p><p>  cout<<"輸入錯誤,請重新選擇"<<endl;</p><p><b>  }</b></p><p><b>  }</b></p><p> 

溫馨提示

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

評論

0/150

提交評論