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

下載本文檔

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

文檔簡(jiǎn)介

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

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

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

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

5、必須清楚主要實(shí)現(xiàn)函數(shù)的目的和作用,需要在程序書寫時(shí)說(shuō)明做適當(dāng)?shù)淖⑨?。在寫課設(shè)報(bào)告時(shí),必須要將主要函數(shù)的功能和參數(shù)做詳細(xì)的說(shuō)明。</p><p>  4、通過(guò)多組數(shù)據(jù)來(lái)檢測(cè)該系統(tǒng)的穩(wěn)定性和正確性。</p><p>  3.3 課程設(shè)計(jì)報(bào)告的內(nèi)容及要求 </p><p>  在完成課題驗(yàn)收后,學(xué)生應(yīng)在規(guī)定的時(shí)間內(nèi)完成課程設(shè)計(jì)報(bào)告一份(不少于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)特征,以及各種存儲(chǔ)結(jié)構(gòu)的特點(diǎn)及使用范圍。</p><p>  熟練掌握哈夫曼樹的建立和哈夫曼編碼方法。</p><p>  掌握用指針類型描述、訪問(wèn)和處理運(yùn)算。</p

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

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

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

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

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

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

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

14、樹用鄰接矩陣作為存儲(chǔ)結(jié)構(gòu),借助靜態(tài)鏈表來(lá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è)計(jì)</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)到每個(gè)葉子節(jié)點(diǎn)所經(jīng)過(guò)的路徑分支組成的0和1的序列便為該節(jié)點(diǎn)對(duì)應(yīng)字符的編碼,稱之為赫夫曼編碼。</p><p>  最簡(jiǎn)單的二進(jìn)制編碼方式是等長(zhǎng)編碼。若采用不等

16、長(zhǎng)編碼,讓出現(xiàn)頻率高的字符具有較短的編碼,讓出現(xiàn)頻率低的字符具有較長(zhǎng)的編碼,這樣可能縮短傳送電文的總長(zhǎng)度。赫夫曼樹課用于構(gòu)造使電文的編碼總長(zhǎng)最短的編碼方案。</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)//找兩個(gè)最小的權(quán)值<

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

21、樹就是我們所說(shuō)的最優(yōu)二叉樹,即哈夫曼樹。</p><p>  以上為哈夫曼樹的建立過(guò)程,下面為哈夫曼編碼的過(guò)程,從葉子節(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> ?。?)譯碼:對(duì)于已經(jīng)建好的哈夫曼樹,要對(duì)其進(jìn)行譯

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

23、寫入目錄下的codefile.txt中。</p><p> ?。?)完成譯碼功能:打開根目錄下codefile.txt文件,讀取里面的編碼,對(duì)其中的編碼進(jìn)行譯碼,并將得到的內(nèi)容寫入根目錄下的文件txtfile.txt中。</p><p><b>  (6)打印編碼</b></p><p><b> ?。?)打印哈夫曼樹</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>  在這里,有一個(gè)要注意的問(wèn)題,在程序剛開始運(yùn)行的時(shí)候,需要先用“i”命令對(duì)哈夫曼樹進(jìn)行初始化。若不進(jìn)行初始化

25、,則表明哈夫曼樹并未建立,這樣就無(wú)法進(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.輸入的字符以及其對(duì)應(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>  此算法的時(shí)間復(fù)雜度為:O(n),n為哈夫曼樹的結(jié)點(diǎn)個(gè)數(shù)。在對(duì)哈夫曼編碼/譯碼器算法設(shè)計(jì)過(guò)程中,主要參考了教材中對(duì)哈夫曼編碼/譯碼的算法。在實(shí)現(xiàn)的過(guò)程中遇到了一些問(wèn)題,后來(lái)參考網(wǎng)上的一些代碼,進(jìn)行與自己帶嗎的整合,將編碼/譯碼算法完成。而

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

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

34、ef char **HuffmanCode;//動(dòng)態(tài)分配數(shù)組存儲(chǔ)哈夫曼編碼表</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)//找兩個(gè)最小的權(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)識(shí)符</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為最小的兩個(gè)值中序號(hào)較小的那個(gè)</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;//申請(qǐng)2n-1個(gè)內(nèi)存單元</p><p>  HT=(HuffmanTree)malloc((m+1)*sizeof(HTNode)); // 0號(hào)單元未用</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個(gè)字符編碼的頭指針向量<

49、/p><p>  cd=(char*)malloc(n*sizeof(char)); //分配求編碼的工作空間</p><p>  cd[n-1]='\0'; //編碼結(jié)束符</p><p>  for(i=1;i<=n;i++)//逐個(gè)字符求哈夫曼編碼</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個(gè)字符編碼分配空間</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<<"請(qǐng)輸入結(jié)點(diǎn)的個(gè)數(shù)n:";</p><p>  cin>>num;//輸入結(jié)點(diǎn)個(gè)數(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請(qǐng)依次輸入"<<n<<"個(gè)字符(字符型)\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<<"個(gè)字符:"<<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請(qǐng)依次輸入"<<n<<"個(gè)權(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<<"個(gè)字符的權(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<<"字符對(duì)應(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<<"已將字符與對(duì)應(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<<"請(qǐng)輸入你想要編碼的字符"<<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<<"下面對(duì)目錄下文件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個(gè)字節(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<<"字符錯(cuò)誤,無(wú)法編碼!"<&

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<<"下面對(duì)根目錄下文件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、出"打印赫夫曼樹"語(yǔ)句</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è)計(jì)\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請(qǐng)先初始化赫夫曼鏈表,輸入'i'\n";&

111、lt;/p><p>  cout<<"請(qǐng)選擇你要進(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<<"輸入錯(cuò)誤,請(qǐng)重新選擇"<<endl;</p><p><b>  }</b></p><p><b>  }</b></p><p> 

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 眾賞文庫(kù)僅提供信息存儲(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)論