版權(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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 哈夫曼樹_數(shù)據(jù)結(jié)構(gòu)課程設(shè)計
- 應(yīng)用數(shù)據(jù)結(jié)構(gòu)課程設(shè)計---哈夫曼樹
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計---哈夫曼樹的應(yīng)用
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計--哈夫曼樹的應(yīng)用
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計--- 哈夫曼樹的應(yīng)用
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計---哈夫曼編碼
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計報告----哈夫曼
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計----哈夫曼編碼
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計哈夫曼編碼
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計--哈夫曼編碼
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計---哈夫曼編碼
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計哈夫曼編碼
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計----赫夫曼樹
- 數(shù)據(jù)結(jié)構(gòu)-赫夫曼樹-課程設(shè)計
- 數(shù)據(jù)結(jié)構(gòu) 課程設(shè)計之哈夫曼編碼
- 哈夫曼編碼譯碼數(shù)據(jù)結(jié)構(gòu)課程設(shè)計
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計---哈夫曼編碼器
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計---哈夫曼編碼器
- 哈夫曼編碼譯碼數(shù)據(jù)結(jié)構(gòu)課程設(shè)計
- 哈夫曼樹課程設(shè)計
評論
0/150
提交評論