版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
1、<p> 課 程 設(shè) 計 說 明 書</p><p> 課程名稱 _________數(shù)據(jù)結(jié)構(gòu) _______________</p><p> 設(shè)計課題 ________哈夫曼編/譯碼器 _________</p><p> 專 業(yè) ______計算機科學(xué)與技術(shù) _________</p><p> 班 級
2、________ xxxx _____________</p><p> 學(xué) 號 ______ xxxxxxx________________</p><p> 姓 名 ____ xxx ______________</p><p> 完成日期 2014年6月14日 </p>
3、<p><b> 【問題描述】</b></p><p> 打開一篇英文文章,統(tǒng)計該文章中每個字符出現(xiàn)的次數(shù),然后以它們作為權(quán)值,設(shè)計一個哈夫曼編/譯碼系統(tǒng)。利用哈夫曼編碼進行通信可以大大提高信道利用率,縮短信息傳輸時間,降低傳輸成本。這要求在發(fā)送端通過一個編碼系統(tǒng)對待傳輸數(shù)據(jù)預(yù)先編碼,在接收端將傳來的數(shù)據(jù)進行譯碼(復(fù)原)。對于雙工信道(即可以雙向傳輸信息的信道),每端都需要一個
4、完整的編/譯碼系統(tǒng)。試為這樣的信息收發(fā)站編寫一個哈夫曼碼的編/譯碼系統(tǒng)。</p><p><b> 【基本要求】</b></p><p> 以每個字符出現(xiàn)的次數(shù)為權(quán)值,建立哈夫曼樹,求出哈夫曼編碼,對文件yuanwen中的正文進行編碼,將結(jié)果存到文件yiwen中,再對文件yiwen中的代碼進行譯碼,結(jié)果存到textfile中。一個完整的系統(tǒng)應(yīng)具有以下功能:<
5、/p><p> (1) I:初始化(Initialization)。從終端讀入字符集大小n,以及n個字符和n個權(quán)值,建立哈夫曼樹,并將它存于文件hfmTree中。</p><p> (2) E:編碼(Encoding)。利用已建好的哈夫曼樹(如不在內(nèi)存,則從文件hfmTree中讀入),對文件ToBeTran中的正文進行編碼,然后將結(jié)果存入文件CodeFile中。</p>&l
6、t;p> (3) D:譯碼(Decoding)。利用已建好的哈夫曼樹將文件CodeFile中的代碼進行譯碼,結(jié)果存入文件Textfile中。</p><p><b> 【測試數(shù)據(jù)】</b></p><p> 用下表給出的字符集和頻度的實際統(tǒng)計數(shù)據(jù)建立哈夫曼樹,并實現(xiàn)以下英文的編碼和譯碼:“I like playing football”。</p>
7、;<p><b> 【算法思想】</b></p><p> 哈夫曼編\譯碼器的主要功能是先建立哈夫曼樹,然后利用建好的哈夫曼樹生成哈夫曼編碼后進行譯碼 。</p><p> 在數(shù)據(jù)通信中,經(jīng)常需要將傳送的文字轉(zhuǎn)換成由二進制字符0、1組成的二進制串,稱之為編碼。構(gòu)造一棵哈夫曼樹,規(guī)定哈夫曼樹中的左分之代表0,右分支代表1,則從根節(jié)點到每個葉子節(jié)點所經(jīng)
8、過的路徑分支組成的0和1的序列便為該節(jié)點對應(yīng)字符的編碼,稱之為哈夫曼編碼。</p><p> 最簡單的二進制編碼方式是等長編碼。若采用不等長編碼,讓出現(xiàn)頻率高的字符具有較短的編碼,讓出現(xiàn)頻率低的字符具有較長的編碼,這樣可能縮短傳送電文的總長度。哈夫曼樹課用于構(gòu)造使電文的編碼總長最短的編碼方案。 </p><p> 其主要流程圖如圖
9、1-1所示。</p><p> ?。?)設(shè)計包含的幾個方面:① 赫夫曼樹的建立</p><p> 哈夫曼樹的建立由赫夫曼算法的定義可知,初始森林中共有n棵只含有根結(jié)點的二叉樹。算法的第二步是:將當(dāng)前森林中的兩棵根結(jié)點權(quán)值最小的二叉樹,合并成一棵新的二叉樹;每合并一次,森林中就減少一棵樹,產(chǎn)生一個新結(jié)點。顯然要進行n-1次合并,所以共產(chǎn)生n-1個新結(jié)點,它們都是具有兩個孩子的分支結(jié)點。由此
10、可知,最終求得的哈夫曼樹中一共有2n-1個結(jié)點,其中n個結(jié)點是初始森林的n個孤立結(jié)點。并且赫夫曼樹中沒有度數(shù)為1的分支結(jié)點。我們可以利用一個大小為2n--1的一維數(shù)組來存儲赫夫曼樹中的結(jié)點。</p><p><b> ② 哈夫曼編碼 </b></p><p> 要求電文的哈夫曼編碼,必須先定義哈夫曼編碼類型,根據(jù)設(shè)計要求和實際需要定義的類型如下: </p&g
11、t;<p> typedet struct { </p><p> char ch; // 存放編碼的字符 </p><p> char bits[N+1]; // 存放編碼位串 </p><p> int len; // 編碼的長度 </p><p> }CodeNode; // 編碼結(jié)構(gòu)體類型 </p>
12、<p> ?、?代碼文件的譯碼 </p><p> 譯碼的基本思想是:讀文件中編碼,并與原先生成的哈夫曼編碼表比較,遇到相等時,即取出其對應(yīng)的字符存入一個新串中。</p><p><b> 【模塊劃分】</b></p><p> 問題分析哈夫曼樹的定義</p><p> 1.哈夫曼樹節(jié)點的數(shù)據(jù)類型定
13、義為:</p><p> typedef struct{ //哈夫曼樹的結(jié)構(gòu)體</p><p><b> char ch;</b></p><p> int weight; //權(quán)值</p><p> int parent,lchild,rchild;</p&g
14、t;<p> }htnode,*hfmtree;</p><p> 2)所實現(xiàn)的功能函數(shù)如下</p><p> 1、void hfmcoding(hfmtree &HT,hfmcode &HC,int n)初始化哈夫曼樹,處理InputHuffman(Huffman Hfm)函數(shù)得到的數(shù)據(jù),按照哈夫曼規(guī)則建立2叉樹。此函數(shù)塊調(diào)用了Select()函數(shù)。&
15、lt;/p><p> 2、void Select(hfmtree &HT,int a,int *p1,int *p2) //Select函數(shù),選出HT樹到a為止,權(quán)值最小且parent為0的2個節(jié)點</p><p> 3、Encoding </p><p> 編碼功能:對輸入字符進行編碼</p><p> 4、D
16、ecoding</p><p> 譯碼功能: 利用已建好的哈夫曼樹將文件codefile.txt中的代碼進行譯碼,結(jié)果存入文件textfile.dat 中。</p><p> 5.主函數(shù)的簡要說明,主函數(shù)主要設(shè)計的是一個分支語句,讓用戶挑選所實現(xiàn)的功能。</p><p> 使用鏈樹存儲,然后分別調(diào)用統(tǒng)計頻數(shù)函數(shù),排序函數(shù),建立哈夫曼函數(shù),編碼函數(shù),譯碼函數(shù)來實
17、現(xiàn)功能。</p><p> 3)系統(tǒng)功能模塊圖:</p><p><b> 【數(shù)據(jù)結(jié)構(gòu)】</b></p><p> (1)①哈夫曼樹的存儲結(jié)構(gòu)描述為: </p><p> #define N 50 // 葉子結(jié)點數(shù) </p><p> #define M 2*N-1 // 哈夫曼樹中結(jié)點
18、總數(shù) </p><p> typedef struct { </p><p> int weight; // 葉子結(jié)點的權(quán)值 </p><p> int lchild, rchild, parent; // 左右孩子及雙親指針 </p><p> }HTNode; // 樹中結(jié)點類型 </p><p> ty
19、pedef HTNode HuffmanTree[M+1]; </p><p><b> ②哈夫曼樹的算法</b></p><p> void CreateHT(HTNode ht[],int n) //調(diào)用輸入的數(shù)組ht[],和節(jié)點數(shù)n</p><p><b> {</b></p
20、><p> int i,k,lnode,rnode;</p><p> int min1,min2;</p><p> for (i=0;i<2*n-1;i++) </p><p> ht[i].parent=ht[i].lchild=ht[i].rchild=-1; //所有結(jié)點的相關(guān)域置初值-1</p&g
21、t;<p> for (i=n;i<2*n-1;i++) //構(gòu)造哈夫曼樹</p><p><b> {</b></p><p> min1=min2=32767; //int的范圍是-32768—32767</p><p> lnode=rnode=
22、-1; //lnode和rnode記錄最小權(quán)值的兩個結(jié)點位置</p><p> for (k=0;k<=i-1;k++)</p><p><b> {</b></p><p> if (ht[k].parent==-1) //只在尚未構(gòu)造二叉樹的結(jié)點中查找</p&g
23、t;<p><b> {</b></p><p> if (ht[k].weight<min1) //若權(quán)值小于最小的左節(jié)點的權(quán)值</p><p><b> {</b></p><p> min2=min1;rnode=lnode;</p><p>
24、 min1=ht[k].weight;lnode=k;</p><p><b> }</b></p><p> else if (ht[k].weight<min2)</p><p><b> {</b></p><p> min2=ht[k].weight;rnode=k;</
25、p><p><b> }</b></p><p><b> }</b></p><p><b> }</b></p><p> ht[lnode].parent=i;ht[rnode].parent=i; //兩個最小節(jié)點的父節(jié)點是i</
26、p><p> ht[i].weight=ht[lnode].weight+ht[rnode].weight; //兩個最小節(jié)點的父節(jié)點權(quán)值為兩個最小節(jié)點權(quán)值之和</p><p> ht[i].lchild=lnode;ht[i].rchild=rnode; //父節(jié)點的左節(jié)點和右節(jié)點</p><p><b>
27、}</b></p><p><b> }</b></p><p><b> ?。?)哈夫曼編碼</b></p><p> void CreateHCode(HTNode ht[],HCode hcd[],int n)</p><p><b> {</b><
28、;/p><p> int i,f,c;</p><p><b> HCode hc;</b></p><p> for (i=0;i<n;i++) //根據(jù)哈夫曼樹求哈夫曼編碼</p><p><b> {</b></p>
29、<p> hc.start=n;c=i;</p><p> f=ht[i].parent;</p><p> while (f!=-1) //循序直到樹根結(jié)點結(jié)束循環(huán)</p><p><b> {</b></p><p> if (ht[f]
30、.lchild==c) //處理左孩子結(jié)點</p><p> hc.cd[hc.start--]='0';</p><p> else //處理右孩子結(jié)點</p><p> hc.cd[hc.start--]='1'
31、;;</p><p> c=f;f=ht[f].parent;</p><p><b> }</b></p><p> hc.start++; //start指向哈夫曼編碼hc.cd[]中最開始字符</p><p> hcd[i]=hc;</p&g
32、t;<p><b> }</b></p><p><b> }</b></p><p> void DispHCode(HTNode ht[],HCode hcd[],int n) //輸出哈夫曼編碼的列表</p><p><b> {</b></p>&l
33、t;p><b> int i,k;</b></p><p> printf(" 輸出哈夫曼編碼:\n"); </p><p> for (i=0;i<n;i++) //輸出data中的所有數(shù)據(jù),即A-Z</p><p><b> {&
34、lt;/b></p><p> printf(" %c:\t",ht[i].data); </p><p> for (k=hcd[i].start;k<=n;k++) //輸出所有data中數(shù)據(jù)的編碼</p><p><b> {</b
35、></p><p> printf("%c",hcd[i].cd[k]); </p><p><b> }</b></p><p> printf("\n");</p><p><b> }</b><
36、/p><p><b> }</b></p><p> void editHCode(HTNode ht[],HCode hcd[],int n) //編碼函數(shù)</p><p><b> {</b></p><p> char string[MAXSIZE];
37、 </p><p> int i,j,k;</p><p> scanf("%s",string); //把要進行編碼的字符串存入string數(shù)組中</p><p> printf("\n輸出編碼結(jié)果:\n");</p><p> for
38、 (i=0;string[i]!='#';i++) //#為終止標志</p><p><b> {</b></p><p> for (j=0;j<n;j++)</p><p><b> {</b></p><p> if(string
39、[i]==ht[j].data) //循環(huán)查找與輸入字符相同的編號,相同的就輸出這個字符的編碼</p><p><b> {</b></p><p> for (k=hcd[j].start;k<=n;k++)</p><p><b> {</b></p><p>
40、 printf("%c",hcd[j].cd[k]);</p><p><b> }</b></p><p> break; //輸出完成后跳出當(dāng)前for循環(huán)</p><p><b> }</b></p><p><b>
41、; }</b></p><p><b> }</b></p><p><b> }</b></p><p><b> ?。?)哈夫曼譯碼</b></p><p> void deHCode(HTNode ht[],HCode hcd[],int n)
42、 //譯碼函數(shù)</p><p><b> {</b></p><p> char code[MAXSIZE];</p><p> int i,j,l,k,m,x;</p><p> scanf("%s",code); //把要進行譯碼的字符串存
43、入code數(shù)組中</p><p> while(code[0]!='#')</p><p> for (i=0;i<n;i++)</p><p><b> {</b></p><p> m=0; //m為想同編碼個數(shù)的計數(shù)器<
44、/p><p> for (k=hcd[i].start,j=0;k<=n;k++,j++) //j為記錄所存儲這個字符的編碼個數(shù)</p><p><b> {</b></p><p> if(code[j]==hcd[i].cd[k]) //當(dāng)有相同編碼時m值加1</p><p>&
45、lt;b> m++;</b></p><p><b> }</b></p><p> if(m==j) //當(dāng)輸入的字符串與所存儲的編碼字符串個數(shù)相等時則輸出這個的data數(shù)據(jù)</p><p><b> {</b></p>
46、<p> printf("%c",ht[i].data);</p><p> for(x=0;code[x-1]!='#';x++) //把已經(jīng)使用過的code數(shù)組里的字符串刪除</p><p><b> {</b></p><p> code[x]=code[x+j];
47、</p><p><b> }</b></p><p><b> }</b></p><p><b> }</b></p><p><b> }</b></p><p><b> 【測試情況】</b>
48、</p><p> 程序運行時,進入的主界面如圖:</p><p> (2)選擇1進入,創(chuàng)建名稱為yuanwen的文件,如圖:</p><p> (3)輸入英語原文為 I like playing football ,如圖所示:</p><p> (4)程序?qū)υ倪M行編碼運行輸出結(jié)果,程序如圖:</p><p>
49、;<b> 【心得】</b></p><p> 在我自己課程設(shè)計中,就在編寫好源代碼后的調(diào)試中出現(xiàn)了不少的錯誤,遇到了很多麻煩及困難,我的調(diào)試及其中的錯誤和我最終找出錯誤,修改為正確的能夠執(zhí)行的程序中,通過分析,我學(xué)到了:</p><p> 在定義頭文件時可多不可少,即我們可多寫些頭文件,肯定不會出錯,但是若沒有定義所引用的相關(guān)頭文件,必定調(diào)試不通過;</
50、p><p> 在執(zhí)行譯碼操作時,不知什么原因,總是不能把要編譯的二進制數(shù)與編譯成的字符用連接號連接起來,而是按順序直接放在一起,視覺效果不是很好。還有就是,很遺憾的是,我們的哈夫曼編碼/譯碼器沒有像老師要求的那樣完成編一個文件的功能,這是我們設(shè)計的失敗之處。</p><p> 通過本次數(shù)據(jù)結(jié)構(gòu)的課程設(shè)計,我學(xué)習(xí)了很多在上課沒懂的知識,并對求哈夫曼樹及哈夫曼編碼/譯碼的算法有了更加深刻的了解
51、,更鞏固了課堂中學(xué)習(xí)有關(guān)于哈夫曼編碼的知識</p><p><b> 【源程序】</b></p><p> #include<stdio.h></p><p> #include<stdlib.h></p><p> #include<string.h></p>
52、<p> #define N 5000</p><p> #define m 128 //葉子結(jié)點個數(shù),即字符總類數(shù)</p><p> #define M 2*m-1 //哈夫曼樹的節(jié)點數(shù) </p><p> char CH[N]; //記錄原文字符數(shù)組</p><p> char YW[N];
53、 //記錄譯文字符數(shù)組</p><p> typedef char * Hcode[m+1]; //存放哈夫曼字符編碼串的頭指針的數(shù)組</p><p> typedef struct</p><p><b> {</b></p><p><b> char a;</b></p&g
54、t;<p><b> int num;</b></p><p> }dangenode; //記錄單個字符的類別和出現(xiàn)的次數(shù)</p><p> typedef struct</p><p><b> {</b></p><p> dangenode b[129
55、];</p><p><b> int tag;</b></p><p> }jilunode; //統(tǒng)計原文出現(xiàn)的字符種類數(shù)</p><p> typedef struct node</p><p><b> {</b></p><p> i
56、nt weight; //結(jié)點權(quán)值</p><p> int parent; //雙親下標</p><p> int Lchild; //左孩子結(jié)點的下標</p><p> int Rchild; //右孩子的下標</p><p> }htnode,hn[M];//靜
57、態(tài)三叉的哈夫曼樹的定義</p><p> void jianliwenjian()</p><p><b> {</b></p><p><b> FILE *fp;</b></p><p> printf("現(xiàn)在建立文件,以存儲原文(文件名稱默認為yuanwen)\n"
58、);</p><p> printf(" 文件建立中......\n");</p><p> if((fp=fopen("yuanwen","wb"))==NULL) //建立文件</p><p><b> {</b></p><
59、;p> printf("Cannot open file\n");</p><p><b> exit(0);</b></p><p><b> }</b></p><p> printf("文件已建立,名稱為:yuanwen");</p><p&g
60、t; fclose(fp); //關(guān)閉文件</p><p><b> }</b></p><p> void luruyuanwen() //原文輸入完后,將其保存到文件yuanwen中</p><p><b> {</b></p&g
61、t;<p><b> char ch;</b></p><p><b> FILE *fp;</b></p><p> if((fp=fopen("yuanwen","wb"))==NULL) //打開文件</p><p><b> {<
62、;/b></p><p> printf("Cannot open file\n");</p><p><b> exit(0);</b></p><p><b> }</b></p><p> printf("請輸入原文(結(jié)束標志為:^)\n"
63、);</p><p><b> do</b></p><p><b> {</b></p><p> ch=getchar();</p><p> fputc(ch,fp); //將字符保存到文件中</p><p> }while(ch!=&
64、#39;^'); //判斷結(jié)束</p><p> getchar(); //接收回車命令符</p><p> fclose(fp); //關(guān)閉文件</p><p> } </p><p> void min_2(hn
65、ht,int n,int *tag1,int *tag2)//在建哈夫曼樹的過程中,選擇權(quán)值小的兩</p><p> { //個結(jié)點</p><p> int i,min,s; </p><p><b> min=N;</b></p><
66、;p> for(i=1;i<=n;i++) </p><p> if(ht[i].weight<min&&ht[i].parent==0) </p><p><b> { </b></p><p> min=ht[i].weight; </p><p> *tag1=i;
67、 //記錄權(quán)值最小的結(jié)點下標</p><p><b> } </b></p><p><b> min=N;</b></p><p> for(i=1;i<=n;i++) </p><p> if(ht[i].weight<min&&
68、ht[i].parent==0&&i!=*tag1)</p><p><b> { </b></p><p> min=ht[i].weight; </p><p><b> *tag2=i; </b></p><p><b> } </b></p
69、><p> if(ht[*tag1].weight==ht[*tag2].weight&&ht[*tag2].Lchild!=0)</p><p><b> {</b></p><p> s=(*tag1); //如果結(jié)點權(quán)值相同,先出現(xiàn)的放在哈夫曼樹的左邊</p><p>
70、 (*tag1)=(*tag2);</p><p> (*tag2)=s;</p><p><b> }</b></p><p><b> } </b></p><p> void chuangjian(jilunode * jilu,hn ht) //建立哈夫曼樹、以及對原&l
71、t;/p><p><b> { </b></p><p> FILE *fp;//文字符的類別和數(shù)量統(tǒng)計</p><p> int i=-1,j,s=0,tag1,tag2;</p><p><b> // s=0;</b></p><p><b> //
72、 i=-1;</b></p><p> //char ch;</p><p> if((fp=fopen("yuanwen","rb"))==NULL) //以只讀的方式打開文件</p><p><b> {</b></p><p> printf(&quo
73、t;Cannot open file\n");</p><p><b> exit(0);</b></p><p><b> }</b></p><p> while(!feof(fp)) //判斷文件指示標志是否移動到了文件尾處</p><p><b>
74、 {</b></p><p><b> char ch;</b></p><p> ch=fgetc(fp);</p><p> if(ch!='^') //判斷字符是否是結(jié)束標志</p><p><b> {</b></p>
75、<p><b> ++i;</b></p><p><b> CH[i]=ch;</b></p><p> for(j=1;j<=jilu->tag;j++) </p><p><b> {</b></p><p> if(CH[i]==jil
76、u->b[j].a)</p><p><b> {</b></p><p> jilu->b[j].num++;</p><p><b> break;</b></p><p><b> }</b></p><p><b>
77、 }</b></p><p> if(j-1==jilu->tag&&CH[i]!=jilu->b[j-1].a)</p><p><b> {</b></p><p> jilu->tag++;</p><p> jilu->b[jilu->tag].
78、a=CH[i];</p><p> jilu->b[jilu->tag].num=1;</p><p><b> }</b></p><p><b> }</b></p><p><b> }</b></p><p> jilu-&
79、gt;tag--;</p><p> fclose(fp); //關(guān)閉文件</p><p> printf("原文中的各字符統(tǒng)計狀況如下:\n");</p><p> printf("*^*^*^*^*^*^*^*^**^*^*^**^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^
80、*^*^*\n");</p><p> for(i=1;i<=jilu->tag;i++)</p><p><b> { </b></p><p><b> s++;</b></p><p> printf("'%c'的個數(shù)為:%d &qu
81、ot;,jilu->b[i].a,jilu->b[i].num);</p><p> if(s%4==0) //每行放四個數(shù)據(jù)</p><p> printf("\n");</p><p><b> }</b></p><p> printf(&q
82、uot;\n"); </p><p> for(i=1;i<=2*(jilu->tag)-1;i++)</p><p><b> {</b></p><p> if(i<=jilu->tag)</p><p><b> {</b></p>&
83、lt;p> ht[i].weight=jilu->b[i].num; //初始化葉子結(jié)點權(quán)值</p><p> ht[i].Lchild=0; //初始化葉子結(jié)點左孩子</p><p> ht[i].parent=0; //初始化葉子結(jié)點父母</p><p> ht[i].Rchild=0;
84、 //初始化葉子結(jié)點右孩子</p><p><b> }</b></p><p><b> else</b></p><p><b> {</b></p><p> ht[i].Lchild=0; //初始化非葉子結(jié)點左孩子&l
85、t;/p><p> ht[i].parent=0; //初始化非葉子結(jié)點父母</p><p> ht[i].Rchild=0; //初始化非葉子結(jié)點右孩子</p><p> ht[i].weight=0; //初始化非葉子結(jié)點權(quán)值</p><p><b> }</b></p&g
86、t;<p><b> }</b></p><p> for(i=jilu->tag+1;i<=2*(jilu->tag)-1;i++) </p><p><b> { </b></p><p> min_2(ht,i-1,&tag1,&tag2); // 需找權(quán)值小的
87、兩個父母為0的結(jié)點</p><p> ht[tag1].parent=i;</p><p> ht[tag2].parent=i;</p><p> ht[i].Lchild=tag1;</p><p> ht[i].Rchild=tag2;</p><p> ht[i].weight=ht[tag1].we
88、ight+ht[tag2].weight;</p><p><b> }</b></p><p><b> }</b></p><p> void bianma(jilunode * jilu,hn ht,Hcode hc,int n) //哈夫曼樹建完后,對葉</p><p>
89、; { //子結(jié)點逐個編碼</p><p> char * cd;</p><p> int start,i,p,c;</p><p> cd=(char *)malloc((n+1)*sizeof(char)); //申請存儲字符的臨時空間<
90、;/p><p> cd[n-1]='\0'; //加結(jié)束標志</p><p> for(i=1;i<=n;i++)</p><p><b> {</b></p><p> start=n-1;</p><p><b
91、> c=i;</b></p><p> p=ht[i].parent;</p><p> while(p!=0)</p><p><b> {</b></p><p><b> --start;</b></p><p> if(ht[p].Lch
92、ild==c)</p><p> cd[start]='1'; //結(jié)點在左邊置1</p><p> if(ht[p].Rchild==c)</p><p> cd[start]='0'; //結(jié)點在右邊置0</p><p><b> c=p
93、;</b></p><p> p=ht[p].parent;</p><p><b> }</b></p><p> printf("%c的編碼為:%s\n",jilu->b[i].a,&cd[start]);</p><p> hc[i]=(char *)mallo
94、c((n-start)*sizeof(char)); //為字符數(shù)組分配空間</p><p> strcpy(hc[i],&cd[start]);//將臨時空間中的編碼復(fù)制到字符數(shù)組中</p><p><b> }</b></p><p> free(cd); //釋放臨時空間<
95、/p><p><b> }</b></p><p> void bianmabaocun(Hcode hc,jilunode * jilu) //將原文以編碼的形式保存到</p><p> { //文件yiwen中
96、</p><p><b> int i,j;</b></p><p><b> FILE *fp;</b></p><p> if((fp=fopen("yiwen","wb"))==NULL) //以寫的方式打開文件</p><p><
97、b> {</b></p><p> printf("Cannot open file\n");</p><p> exit(0); //文件打開失敗退出</p><p><b> }</b></p><p> fo
98、r(i=0;i<=N&&CH[i]!='^';i++) </p><p><b> {</b></p><p> for(j=1;j<=jilu->tag;j++)</p><p> if(CH[i]==jilu->b[j].a)</p><p><b&
99、gt; {</b></p><p> fputs(hc[j],fp); //將文件中的字符輸出到字符數(shù)組中</p><p> printf("%s",hc[j]);</p><p><b> }</b></p><p><b> }</b&
100、gt;</p><p> fclose(fp); //關(guān)閉文件</p><p><b> }</b></p><p> void yiwen(Hcode hc,jilunode * jilu) //讀取yiwen中的編碼,并將其翻譯</p><p&
101、gt; { //為原文存放到字符數(shù)組YW[N]中</p><p> int tag1,tag2,i,j,s=0;</p><p> FILE *fp; //文件指針</p><p><b> ch
102、ar *c;</b></p><p> if((fp=fopen("yiwen","rb"))==NULL) //以只讀的方式打開文件</p><p><b> {</b></p><p> printf("cannot open file\n");<
103、;/p><p><b> exit(0);</b></p><p><b> }</b></p><p> while(!feof(fp))</p><p><b> {</b></p><p> tag1=1; //結(jié)束
104、for循環(huán)的輔助標志</p><p> tag2=1; //結(jié)束for循環(huán)的輔助標志</p><p> c=(char *)malloc(200*sizeof(char));</p><p> for(i=0;i<200&&tag1;i++)</p><p><b> {
105、</b></p><p> c[i]=fgetc(fp); //將文件中的字符輸出到數(shù)組中</p><p> c[i+1]='\0'; //加結(jié)束標志</p><p> for(j=1;(j<=jilu->tag)&&tag2;j++)</p><p>
106、;<b> {</b></p><p> if(strcmp(hc[j],c)==0) //將編碼與原文字符匹配</p><p><b> {</b></p><p> YW[s]=jilu->b[j].a; //匹配成功后將字符保存到數(shù)組YW中</p><p&g
107、t;<b> tag1=0;</b></p><p><b> s++;</b></p><p> free(c); //釋放臨時字符存儲空間</p><p><b> tag2=0;</b></p><p><b> }</b>
108、;</p><p><b> }</b></p><p><b> }</b></p><p><b> }</b></p><p> YW[s]='\0';</p><p><b> }</b></
109、p><p> void baocunyiwen() //將翻譯的譯文保存到文件textfile中</p><p><b> {</b></p><p><b> int i;</b></p><p><b> FILE *fp;</b></p>
110、<p> if((fp=fopen("textfile","wb"))==NULL)</p><p><b> {</b></p><p> printf("Cannot open file\n");</p><p><b> exit(0);</b&
111、gt;</p><p><b> }</b></p><p> for(i=0;YW[i]!='\0';i++)</p><p><b> {</b></p><p> fputc(YW[i],fp); //將數(shù)組中的字符保存到文件中</p>
112、<p> putchar(YW[i]);</p><p><b> }</b></p><p> fclose(fp); //關(guān)閉文件</p><p><b> }</b></p><p> void duquyiwen()
113、 //從文件textfile中讀取譯文</p><p><b> {</b></p><p><b> char ch;</b></p><p><b> FILE *fp;</b></p><p> if((fp=fopen("textfile
114、","rb"))==NULL) //以只讀的方式打開文件</p><p><b> {</b></p><p> printf("cannot open file\n");</p><p><b> exit(0);</b></p><
115、p><b> }</b></p><p> while(!feof(fp))</p><p><b> {</b></p><p> ch=fgetc(fp); //將文件中的字符賦給字符變量ch</p><p> printf("%c"
116、,ch); //輸出字符</p><p><b> }</b></p><p> fclose(fp); //關(guān)閉文件</p><p><b> }</b></p><p> void duquyuanwen()
117、 //從文件yuanwen中讀取原文</p><p><b> {</b></p><p><b> char ch;</b></p><p><b> FILE *fp;</b></p><p> if((fp=fopen("yuan
118、wen","rb"))==NULL) //以只讀的方式打開文件</p><p><b> {</b></p><p> printf("cannot open file\n");</p><p><b> exit(0);</b></p>&l
119、t;p><b> }</b></p><p> while(!feof(fp))</p><p><b> {</b></p><p> ch=fgetc(fp); //將文件中的字符賦給字符變量ch</p><p> printf("%c",ch);
120、 //輸出字符</p><p><b> }</b></p><p> fclose(fp); //關(guān)閉文件</p><p><b> }</b></p><p> void duqubianma() //從文件yiw
121、en中讀取原文</p><p><b> {</b></p><p><b> char ch;</b></p><p><b> FILE *fp;</b></p><p> if((fp=fopen("yiwen","rb")
122、)==NULL)</p><p><b> {</b></p><p> printf("cannot open file\n");</p><p><b> exit(0);</b></p><p><b> }</b></p>&l
123、t;p> while(!feof(fp))</p><p><b> {</b></p><p> ch=fgetc(fp); //將文件中的字符賦給字符變量ch</p><p> printf("%c",ch); //輸出字符</p><p><b> }&l
124、t;/b></p><p> fclose(fp); //關(guān)閉文件</p><p><b> }</b></p><p> void main()</p><p><b> { </b></p><p> int a,c,tep=1;</p&g
125、t;<p> hn humtree; //定義用三叉鏈表方式實現(xiàn)的哈夫曼樹</p><p> Hcode hc; //定義存放哈夫曼字符編碼串的頭指針的數(shù)組</p><p> jilunode ji; //定義存放字符種類數(shù)量的棧</p><
126、p> jilunode *jilu;</p><p> jilu=&ji; //取指針</p><p> jilu->tag=0; //字符種類數(shù)標志初始化</p><p> while(tep)</p><p><b> {</
127、b></p><p> printf(" (*^__^*) 哈夫曼編碼系統(tǒng)歡迎您(*^__^*) \n");</p><p> printf("*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*\n");</p><p> pri
128、ntf(" 1--創(chuàng)建存貯原文件的文件\n");</p><p> printf(" 2--輸入原文\n");</p><p> printf(" 3--對原文編碼\n");</p><p> printf(" 4--對編碼譯碼\n");</p
129、><p> printf(" 5--輸出原文\n");</p><p> printf(" 6--輸出譯碼\n");</p><p> printf(" 7--輸出譯文\n");</p><p> printf(" 8--退出\n&quo
130、t;);</p><p> printf("注意:如果您未創(chuàng)建原文件原文操作,請不要進行后續(xù)項操作!\n");</p><p> printf("*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*\n");</p><p> printf(&qu
131、ot;請輸入服務(wù)選項(1-8):");</p><p> scanf("%d",&a);</p><p> getchar();</p><p><b> switch(a)</b></p><p><b> {</b></p><p
132、><b> case 1:</b></p><p> jianliwenjian(); //建立存儲字符的文件</p><p> printf("是否繼續(xù)?(1.YES 2,NO ):");</p><p> scanf("%d",&c);</p
133、><p> if(c==1)tep=1;</p><p><b> else</b></p><p><b> tep=0;</b></p><p> system("cls");</p><p><b> break;</b>
134、</p><p><b> case 2:</b></p><p> system("cls");</p><p> luruyuanwen(); //將原文錄入到文件中</p><p> printf("\n注意:原文件將保存在名稱為yuanwen的文件中!\n&quo
135、t;);</p><p> printf("是否繼續(xù)?(1.YES 2,NO ):");</p><p> scanf("%d",&c);</p><p> if(c==1)tep=1;</p><p><b> else</b></p><
136、p><b> tep=0;</b></p><p> system("cls");</p><p><b> break;</b></p><p><b> case 3:</b></p><p> chuangjian(jilu,humtr
137、ee); //創(chuàng)建哈夫曼樹</p><p> printf("\n各字符編碼結(jié)果為:\n");</p><p> bianma(jilu,humtree,hc,jilu->tag); //對哈夫曼樹的葉子結(jié)點編碼</p><p> printf("原文的編碼為:\n");</p>
138、<p> printf("*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*\n");</p><p> bianmabaocun(hc,jilu); //保存編碼</p><p> printf("\n
139、*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*\n");</p><p> printf("\n注意:原文的編碼將保存在以名稱為yiwen的文件中!\n");</p><p> printf("是否繼續(xù)?(1.YES 2,NO ):
溫馨提示
- 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)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計實驗報告
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計實驗報告(赫夫曼編碼)
- 06年數(shù)據(jù)結(jié)構(gòu)課程設(shè)計實驗報告
- 《數(shù)據(jù)結(jié)構(gòu)課程設(shè)計》航班查詢系統(tǒng)實驗報告
- 《數(shù)據(jù)結(jié)構(gòu)》課程設(shè)計實驗報告---有關(guān)查找的操作
- 數(shù)據(jù)結(jié)構(gòu)各種排序算法的課程設(shè)計實驗報告
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計圖書管理系統(tǒng)實驗報告
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計avl樹實現(xiàn)及其分析實驗報告
- 《數(shù)據(jù)結(jié)構(gòu)》課程設(shè)計實驗報告--多種排序方式的比較
- 數(shù)據(jù)結(jié)構(gòu)-鄰接表存儲及遍歷-課程設(shè)計-實驗報告
- 數(shù)據(jù)結(jié)構(gòu)-無向圖的操作-課程設(shè)計-實驗報告
- 國開(電大)數(shù)據(jù)結(jié)構(gòu)課程實驗報告
- 數(shù)據(jù)結(jié)構(gòu)實驗報告-串
- 數(shù)據(jù)結(jié)構(gòu)-串的存儲表示及基本操作--課程設(shè)計-實驗報告
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計實驗報告心得體會鏈表c語言
- 數(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è)計報告
評論
0/150
提交評論