版權(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ì)報(bào)告</p><p> 課程名稱 :赫夫曼編碼系統(tǒng)</p><p> 姓 名 : </p><p> 學(xué) 號(hào) : </p><p> 專 業(yè) : </p><p> 班
2、 級(jí) : </p><p> 指導(dǎo)教師 : </p><p><b> 二〇一二年 十二月</b></p><p> 赫 夫 曼 編 碼 系 統(tǒng)</p><p> 目錄 Contents</p><p><
3、;b> 1.課程小組2</b></p><p> 1.1.小組成員及分工2</p><p> 2.設(shè)計(jì)目的和要求2</p><p><b> 3.需求分析2</b></p><p><b> 4.設(shè)計(jì)說(shuō)明2</b></p><p&g
4、t; 4.1.文件編碼(加密)2</p><p> 4.2.文件解碼(解密)3</p><p><b> 5.詳細(xì)設(shè)計(jì)3</b></p><p> 5.1.程序主體結(jié)構(gòu)3</p><p> 5.2.主要算法說(shuō)明3</p><p> 5.2.1.Huffman樹(shù)3
5、</p><p> 5.2.2.Huffman編碼5</p><p> 5.2.3.字符權(quán)重計(jì)算6</p><p> 5.2.4.字符解碼9</p><p> 6.實(shí)驗(yàn)結(jié)果10</p><p> 6.1.實(shí)驗(yàn)結(jié)果說(shuō)明10</p><p> 6.2.程序運(yùn)行截圖
6、11</p><p> 7.設(shè)計(jì)體會(huì)12</p><p> 8.參考文獻(xiàn)13</p><p> 9.附:程序代碼13</p><p><b> 課程小組</b></p><p><b> 小組成員及分工</b></p><p>&
7、lt;b> …</b></p><p><b> 設(shè)計(jì)目的和要求</b></p><p> 通過(guò)課程設(shè)計(jì),讓學(xué)生進(jìn)一步熟悉與鞏固數(shù)據(jù)結(jié)構(gòu)中常用算法,加深體會(huì)利用數(shù)據(jù)結(jié)構(gòu)的算法解決實(shí)際問(wèn)題的能力,培養(yǎng)學(xué)生進(jìn)行復(fù)雜程序設(shè)計(jì)的技能,提高學(xué)生的思維能力、并促進(jìn)其綜合應(yīng)用能力、分析能力和團(tuán)隊(duì)合作能力的提高。</p><p><
8、;b> 需求分析</b></p><p> 隨著網(wǎng)絡(luò)信息科技的不斷高速發(fā)展,網(wǎng)絡(luò)上的問(wèn)題也不斷顯露出來(lái),特別是人們特別關(guān)注的安全隱私問(wèn)題,所以文件的傳輸安全性要特別地亟待解決和提高。</p><p> 本次的課程設(shè)計(jì)以赫夫曼編碼為題,設(shè)計(jì)出赫夫曼文件編碼系統(tǒng),旨在對(duì)文件中的內(nèi)容進(jìn)行分析、統(tǒng)計(jì)、處理,進(jìn)而按照赫夫曼編碼的理論,對(duì)文件進(jìn)行簡(jiǎn)單加密。特別是,不同的文本文件
9、有不同的字符處理形式,所以因此每一個(gè)文本都會(huì)有一個(gè)相應(yīng)的密鑰,用于對(duì)文本的解碼。</p><p><b> 設(shè)計(jì)說(shuō)明</b></p><p> 本次編寫的程序按著對(duì)文件的編碼(加密)和解碼(解密)的兩大步驟展開(kāi)。</p><p><b> 文件編碼(加密)</b></p><p> 首先選擇
10、文件編碼程序。進(jìn)入程序后,會(huì)要求操作人員選擇將要編碼的文件,并將其導(dǎo)入到程序中,程序正確導(dǎo)入文件后將會(huì)對(duì)文件從開(kāi)始至結(jié)束掃描一遍,對(duì)文件中的字符進(jìn)行統(tǒng)計(jì),在最后計(jì)算出每個(gè)字符出現(xiàn)的頻率,并將頻率換算成每個(gè)字符相應(yīng)的權(quán)重。然后根據(jù)得到的字符權(quán)重,構(gòu)造赫夫曼樹(shù)并因此完成赫夫曼編碼(至此,文件的導(dǎo)入分析過(guò)程已完成)。</p><p> 然后讓操作人員選擇對(duì)文件進(jìn)行編碼。此時(shí),程序?qū)?huì)繼續(xù)打開(kāi)文件,繼續(xù)掃描一遍,并在掃
11、描的過(guò)程中將掃描到得字符根據(jù)剛才編好的赫夫曼編碼進(jìn)行對(duì)照,將對(duì)應(yīng)的赫夫曼編碼寫入另一個(gè)文件(即加密的文件),所以,如果用戶代開(kāi)加密的文件即看到里面全是二進(jìn)制代碼,并不能分析出里面究竟是什么內(nèi)容。(至此,加密的文件應(yīng)經(jīng)生成)。</p><p> 最后,因?yàn)槊總€(gè)文件中的內(nèi)容不同,所以每個(gè)文件的赫夫曼編碼也不同,而赫夫曼編碼是根據(jù)字符的權(quán)重生成的,所以每個(gè)文件都對(duì)應(yīng)一個(gè)字符權(quán)重系列(即密鑰),如果失去這個(gè)密鑰,即使對(duì)
12、文件進(jìn)行了加密,也不同解密文件的內(nèi)容,即文件加密失效,所以在生成加密文件后,一定要導(dǎo)出文件的字符權(quán)重(即密鑰),以待之后的解碼使用。(至此,文件的加密工作應(yīng)經(jīng)全部完成)。</p><p><b> 文件解碼(解密)</b></p><p> 文件的解碼程序是一步完成的,即要求操作者首先將之前生成的字符權(quán)重(即密鑰)導(dǎo)入程序,程序根據(jù)獲取到得字符權(quán)重,調(diào)用赫夫曼編碼
13、子程序,進(jìn)行赫夫曼編碼。然后程序會(huì)提示操作者將加密后的文件導(dǎo)入程序中,程序會(huì)根據(jù)在程序中獲取到的二進(jìn)制編碼與赫夫曼編碼進(jìn)行對(duì)照識(shí)別,顯示出對(duì)應(yīng)的字符,因此,文件的解密工作完成。</p><p><b> 詳細(xì)設(shè)計(jì)</b></p><p><b> 程序主體結(jié)構(gòu)</b></p><p> 程序主體結(jié)構(gòu)分為文件編碼與文件
14、解碼兩個(gè)子程序。</p><p> 文件編碼后分別導(dǎo)出編碼后文件與文件密鑰。</p><p> 文件解碼需導(dǎo)入編碼文件與文件密鑰,然后顯示文本內(nèi)容。</p><p><b> 主要算法說(shuō)明</b></p><p><b> Huffman樹(shù)</b></p><p>
15、 //HuffmanTree list: list為赫夫曼樹(shù).</p><p> typedef struct</p><p><b> {</b></p><p> char data; //存放字符數(shù)據(jù)</p><p> int weight; //存放字符權(quán)重</p>
16、<p> int parent, lchild, rchild; //分別為根、左子樹(shù)、右子樹(shù)</p><p> }HuffmanTree;</p><p> //Static info: info為存放字符權(quán)重的數(shù)組指針. </p><p> typedef struct</p><p><b> {&l
17、t;/b></p><p> char data; //存放字符數(shù)據(jù)</p><p> int weight; //存放字符權(quán)重</p><p><b> }Static;</b></p><p> //int codeSize: codeSize為字符種類個(gè)數(shù).</
18、p><p> void CreatHuffmanTree(HuffmanTree *&list, Static *info, int codeSize)</p><p><b> {</b></p><p> int i, j, limit;</p><p> int lnode, rnode;</p&
19、gt;<p> int value1, value2;</p><p> HuffmanTree *ptr;</p><p> limit = codeSize * 2 - 1;//limit為赫夫曼樹(shù)結(jié)點(diǎn)個(gè)數(shù)</p><p> if ((list = (HuffmanTree *)malloc(sizeof(HuffmanTree) *
20、limit)) == NULL)</p><p><b> {</b></p><p> printf(" 內(nèi)存不足, 操作失敗!\n");</p><p><b> exit(0);</b></p><p><b> }</b></p>
21、<p> /*******************初始化赫夫曼樹(shù)各結(jié)點(diǎn)信息**************************/</p><p> for(i=0, ptr=list; i<codeSize; ++i, ++ptr)</p><p><b> {</b></p><p> ptr->data =
22、 info[i].data;</p><p> ptr->weight = info[i].weight;</p><p> ptr->parent = ptr->lchild = ptr->rchild = -1;</p><p><b> }</b></p><p> for(; i&
23、lt;limit; ++i, ++ptr)</p><p><b> {</b></p><p> ptr->data = '0';</p><p> ptr->weight = 0;</p><p> ptr->parent = ptr->lchild = ptr->
24、;rchild = -1;</p><p><b> }</b></p><p> /***********************開(kāi)始建立赫夫曼樹(shù)******************************/</p><p> for(i=codeSize; i<limit; ++i)</p><p>&l
25、t;b> {</b></p><p> value1 = value2 = 32767;</p><p> lnode = rnode = -1;</p><p> //此部分函數(shù)功能為選擇權(quán)值最小的兩個(gè)結(jié)點(diǎn)</p><p> for(j=0; j<i; ++j)</p><p>&l
26、t;b> {</b></p><p> if (list[j].parent == -1)</p><p><b> {</b></p><p> if (list[j].weight < value1)</p><p><b> {</b></p>
27、<p> value2 = value1;</p><p> rnode = lnode;</p><p> value1 = list[j].weight;</p><p> lnode = j;</p><p><b> }</b></p><p> else if (l
28、ist[j].weight < value2)</p><p><b> {</b></p><p> value2 = list[j].weight;</p><p> rnode = j;</p><p><b> }</b></p><p><b&g
29、t; }</b></p><p><b> }</b></p><p> //此部分函數(shù)功能為選擇出的結(jié)點(diǎn)建立關(guān)系</p><p> list[lnode].parent = i;</p><p> list[rnode].parent = i;</p><p> list
30、[i].weight = list[lnode].weight + list[rnode].weight;</p><p> list[i].lchild = lnode;</p><p> list[i].rchild = rnode;</p><p><b> }</b></p><p><b>
31、}</b></p><p><b> Huffman編碼</b></p><p> void CreatHuffmanCode(HuffmanTree *list, HuffmanCode &code, int codeSize)</p><p><b> {</b></p><
32、;p> int i, start;</p><p> int flag1, flag2; </p><p> char *tempCode;</p><p> if ((code = (char **)malloc(sizeof(char *) * codeSize)) == NULL)</p><p><b> {
33、</b></p><p> printf(" 內(nèi)存不足, 操作失敗!\n");</p><p><b> exit(0);</b></p><p><b> }</b></p><p> if ((tempCode = (char *)malloc(sizeo
34、f(char) * codeSize)) == NULL)</p><p><b> {</b></p><p> printf(" 內(nèi)存不足, 操作失敗!\n");</p><p><b> exit(0);</b></p><p><b> }</b&
35、gt;</p><p> tempCode[codeSize-1] = '\0';</p><p> /**************************從葉子結(jié)點(diǎn)到根結(jié)點(diǎn)逆向求編碼***********************/</p><p> for(i=0; i<codeSize; ++i)</p><p&g
36、t;<b> {</b></p><p> start = codeSize - 1;</p><p> for(flag1=i, flag2=list[i].parent; flag2 != -1; flag1=flag2, flag2=list[flag2].parent)</p><p><b> {</b>
37、</p><p> if (list[flag2].lchild == flag1)</p><p><b> {</b></p><p> tempCode[--start] = '0';</p><p><b> }</b></p><p><
38、;b> else</b></p><p><b> {</b></p><p> tempCode[--start] = '1';</p><p><b> }</b></p><p><b> }</b></p>&l
39、t;p> if ((code[i] = (char *)malloc(sizeof(char) * (codeSize - start))) == NULL)</p><p><b> {</b></p><p> printf(" 內(nèi)存不足, 操作失敗!\n");</p><p><b> exit
40、(0);</b></p><p><b> }</b></p><p> strcpy(code[i], &tempCode[start]);</p><p><b> }</b></p><p> free(tempCode);</p><p>
41、<b> }</b></p><p><b> 字符權(quán)重計(jì)算</b></p><p> //Data characterList: characterList為動(dòng)態(tài)建立的存放字符種類及在文本中出現(xiàn)次數(shù)的單鏈表.</p><p> typedef struct node</p><p><
42、;b> {</b></p><p> char data;//存放字符數(shù)據(jù)</p><p> int number;//存放字符個(gè)數(shù)</p><p> struct node *next;</p><p><b> }Data;</b></p><p> //此算法中
43、設(shè)計(jì)導(dǎo)入文件操作.</p><p> void DataCount(Static *&info)</p><p><b> {</b></p><p><b> FILE *fp;</b></p><p><b> char ch;</b></p>
44、<p> char choice;</p><p> int characterNumber, typeNumber;</p><p> Data characterList;</p><p> Data *ptr, *current, *previous;</p><p> system("CLS"
45、);</p><p> printf("\n 請(qǐng)輸入需要打開(kāi)的文件名稱: ");</p><p> fflush(stdin);</p><p> gets(fileName);</p><p> while ((fp = fopen(fileName, "rb")) == NULL)</
46、p><p><b> {</b></p><p> printf("\n 您需要打開(kāi)的文件不存在, 是否需要重新打開(kāi)(Y/N)? : ");</p><p> fflush(stdin);</p><p> choice = getchar();</p><p> swi
47、tch (choice)</p><p><b> {</b></p><p><b> case 'Y':</b></p><p> system("CLS");</p><p> printf("\n 請(qǐng)輸入需要打開(kāi)的文件名稱: "
48、);</p><p> fflush(stdin);</p><p> gets(fileName);</p><p><b> continue;</b></p><p><b> case 'N':</b></p><p><b>
49、return;</b></p><p><b> default:</b></p><p><b> break;</b></p><p><b> }</b></p><p><b> }</b></p><p&g
50、t; characterNumber = typeNumber = 0;</p><p> characterList.next = NULL;</p><p> //從文件中讀取信息并統(tǒng)計(jì)</p><p> while ((ch = fgetc(fp)) != EOF)</p><p><b> {</b>&
51、lt;/p><p> current = characterList.next;</p><p> if (current == NULL)</p><p><b> {</b></p><p> if ((ptr = (Data *)malloc(sizeof(Data))) == NULL)</p>
52、<p><b> {</b></p><p> printf(" 內(nèi)存不足, 操作失敗!\n");</p><p><b> exit(0);</b></p><p><b> }</b></p><p> ptr->data =
53、 ch;</p><p> ptr->number = 1;</p><p> ptr->next = characterList.next;</p><p> characterList.next = ptr;</p><p> ++typeNumber;</p><p><b> }
54、</b></p><p><b> else</b></p><p><b> {</b></p><p> while ((current != NULL) && (current->data != ch))</p><p><b> {<
55、/b></p><p> previous = current;</p><p> current = current->next;</p><p><b> }</b></p><p> if (current != NULL)</p><p><b> {<
56、;/b></p><p> ++(current->number);</p><p> ++characterNumber;</p><p><b> }</b></p><p><b> else</b></p><p><b> {<
57、/b></p><p> if ((ptr = (Data *)malloc(sizeof(Data))) == NULL)</p><p><b> {</b></p><p> printf(" 內(nèi)存不足, 操作失敗!\n");</p><p><b> exit(0);&
58、lt;/b></p><p><b> }</b></p><p> ptr->data = ch;</p><p> ptr->number = 1;</p><p> ptr->next = current;</p><p> previous->nex
59、t = ptr;</p><p> ++typeNumber;</p><p> ++characterNumber;</p><p><b> }</b></p><p><b> }</b></p><p><b> }</b></p
60、><p> fclose(fp);</p><p> codeSize = typeNumber;</p><p> info = (Static *)malloc(sizeof(Static) * codeSize);</p><p> current = characterList.next;</p><p>
61、 //將統(tǒng)計(jì)好的字符權(quán)重信息存入權(quán)重文件中</p><p> for (int i=0; i<codeSize; ++i)</p><p><b> {</b></p><p> info[i].data = current->data;</p><p> info[i].weight = (int
62、)(current->number * 100.0 / characterNumber);</p><p> current = current->next;</p><p><b> }</b></p><p><b> }</b></p><p><b> 字符解碼
63、</b></p><p> //此代碼用于比較查找赫夫曼編碼</p><p> bool CompareData(char *tempCode, int &position)</p><p><b> {</b></p><p> for (position = 0; position <
64、; codeSize; ++position)</p><p><b> {</b></p><p> if (strcmp(tempCode, code[position]) == 0)</p><p><b> {</b></p><p> return true;</p>
65、<p><b> }</b></p><p><b> }</b></p><p> return false;</p><p><b> }</b></p><p> void DisplayContext()</p><p>&
66、lt;b> {</b></p><p> InportCharacterWeight();</p><p> CreatHuffmanTree(list, info, codeSize);</p><p> CreatHuffmanCode(list, code, codeSize);</p><p> Inpor
67、tFileCoding();</p><p><b> FILE *fp;</b></p><p> int position;</p><p><b> int end;</b></p><p> char *tempCode;</p><p><b>
68、 char ch;</b></p><p> fp = fopen(fileName, "rb");</p><p> if ((tempCode = (char *)malloc(sizeof(char) * codeSize)) == NULL)</p><p><b> {</b></p>
69、<p> printf(" 內(nèi)存不足, 操作失敗!\n");</p><p><b> exit(0);</b></p><p><b> }</b></p><p><b> end = 0;</b></p><p> /*****
70、*************************此部分為解碼過(guò)程************************/</p><p> printf("\n 文件內(nèi)容為:\n\n ");</p><p> while ((ch = fgetc(fp)) != EOF)</p><p><b> {</b></p&
71、gt;<p> tempCode[end] = ch;</p><p><b> ++end;</b></p><p> tempCode[end] = '\0';</p><p> if (CompareData(tempCode, position))</p><p><b
72、> {</b></p><p> printf("%c", info[position].data);</p><p><b> end = 0;</b></p><p><b> }</b></p><p><b> }</b>
73、</p><p> printf("\n\n 按任意鍵結(jié)束!");</p><p><b> getch();</b></p><p><b> }</b></p><p><b> 實(shí)驗(yàn)結(jié)果</b></p><p><
74、b> 實(shí)驗(yàn)結(jié)果說(shuō)明</b></p><p> 經(jīng)過(guò)多次對(duì)本程序的實(shí)驗(yàn),此次編譯完成的程序可以對(duì)簡(jiǎn)單的文本文件進(jìn)行加密和解密,因?yàn)橄抻趯?duì)文件的基本操作不是太完全清楚,只是匆匆查閱了一些關(guān)于C語(yǔ)言文件操作部分的資料,所以這也是文件操作方面的一個(gè)瑕疵。所以綜上,次此的程序只能進(jìn)行簡(jiǎn)單的加密與解密操作。</p><p><b> 程序運(yùn)行截圖</b>&
75、lt;/p><p> ?。▓D1:赫夫曼加密程序主體窗口)</p><p> ?。▓D2:赫夫曼文件編碼程序窗口)</p><p> ?。▓D3:用于測(cè)試的文本 原始文本內(nèi)內(nèi)容)</p><p> (圖4:導(dǎo)出文件編碼后,在創(chuàng)建的編碼文件中生成的二進(jìn)制數(shù))</p><p> ?。▓D5:導(dǎo)出的文本密鑰(即字符權(quán)重))</
76、p><p> (圖6:赫夫曼文件譯碼程序窗口)</p><p> ?。▓D7:將之前生成的編碼文件與密鑰導(dǎo)入進(jìn)來(lái)后顯示出原來(lái)的文本內(nèi)容)</p><p><b> 設(shè)計(jì)體會(huì)</b></p><p> 進(jìn)過(guò)此次的實(shí)驗(yàn),讓我對(duì)樹(shù)結(jié)構(gòu)及最優(yōu)二叉樹(shù)概念與操作的理解。</p><p> 在此次選擇赫夫曼編
77、碼操作的時(shí)候,本打算用赫夫曼編碼的程序?qū)ξ募M(jìn)行壓縮存儲(chǔ),可是限于不知道怎樣將生成的赫夫曼編碼進(jìn)行bit級(jí)別的存儲(chǔ)(只知道進(jìn)行Byte級(jí)別的存儲(chǔ)),所以壓縮存儲(chǔ)的想法失敗了,之后根據(jù)赫夫曼編碼的結(jié)構(gòu)及生成的文件,不得不讓我想到了文件的加密與解密,于是按著這個(gè)思路來(lái)設(shè)計(jì)了本文件加密解密系統(tǒng)。在設(shè)計(jì)的時(shí)候,曾準(zhǔn)備根據(jù)網(wǎng)上之前對(duì)26個(gè)英文字符的使用統(tǒng)計(jì)來(lái)事先對(duì)字符權(quán)重進(jìn)行分配(這樣加密的文件可解密性增加了),而且考慮到文件中不僅有26個(gè)英文字
78、母,如果對(duì)各種字符的使用頻率進(jìn)行統(tǒng)計(jì),這個(gè)事先工作的負(fù)擔(dān)會(huì)很重,所以之后編寫了自動(dòng)統(tǒng)計(jì)文本字符的頻率程序,這樣工作量會(huì)減小很多(而且文件的可解密性大大減小,但是也帶來(lái)了記錄密鑰的不方便)。</p><p> 總體感覺(jué)程序還行,就是代碼的簡(jiǎn)潔性還是有點(diǎn)差,條理還是不那么清晰。</p><p><b> 參考文獻(xiàn)</b></p><p> [
79、1]嚴(yán)蔚敏、吳偉明.數(shù)據(jù)結(jié)構(gòu).清華大學(xué)出版社.1997.4</p><p> [2]Thomas H.Cormen、Charles E.Leiserson .算法導(dǎo)論.機(jī)械工業(yè)出版社.2006.9</p><p><b> 附:程序代碼</b></p><p> #include<stdio.h></p><
80、;p> #include<conio.h></p><p> #include<string.h></p><p> #include<stdlib.h></p><p><b> //赫夫曼樹(shù)結(jié)構(gòu)</b></p><p> typedef struct</p&g
81、t;<p><b> {</b></p><p> char data;</p><p> int weight;</p><p> int parent, lchild, rchild;</p><p> }HuffmanTree; </p><p><b>
82、 //字符權(quán)重結(jié)構(gòu)</b></p><p> typedef struct</p><p><b> {</b></p><p> char data;</p><p> int weight;</p><p><b> }Static;</b><
83、/p><p> //統(tǒng)計(jì)字符時(shí)所用到的鏈表結(jié)構(gòu)</p><p> typedef struct node</p><p><b> {</b></p><p> char data;</p><p> int number;</p><p> struct node
84、 *next;</p><p><b> }Data;</b></p><p><b> //赫夫曼代碼結(jié)構(gòu)</b></p><p> typedef char** HuffmanCode;</p><p><b> //創(chuàng)建赫夫曼樹(shù)</b></p>&l
85、t;p> void CreatHuffmanTree(HuffmanTree *&list, Static *info, int codeSize);</p><p><b> //創(chuàng)建赫夫曼代碼</b></p><p> void CreatHuffmanCode(HuffmanTree *list, HuffmanCode &code,
86、 int codeSize);</p><p> //從文件中讀取數(shù)據(jù)并計(jì)算各字符出現(xiàn)頻率</p><p> void DataCount(Static *&info);</p><p><b> //文件編碼程序</b></p><p> void FileEncoding();</p>
87、<p><b> //創(chuàng)建文件編碼</b></p><p> void CreatFileCoding();</p><p><b> //導(dǎo)出編碼后文件</b></p><p> void ExportFileEncoding(HuffmanTree *list, HuffmanCode code, i
88、nt codeSize);</p><p> //導(dǎo)出文件中字符權(quán)重</p><p> void ExportCharacterWeight();</p><p><b> //文件譯碼程序</b></p><p> void FileDecoding();</p><p> //導(dǎo)入編
89、碼后的文件</p><p> void InportFileCoding();</p><p> //導(dǎo)入文件中字符權(quán)重</p><p> void InportCharacterWeight();</p><p> //顯示譯碼后的文件內(nèi)容</p><p> void DisplayContext();&l
90、t;/p><p> bool CompareData(char *tempCode, int &position);</p><p> void Bound(char character, int size);</p><p><b> //赫夫曼樹(shù)</b></p><p> HuffmanTree *lis
91、t;</p><p><b> //赫夫曼代碼</b></p><p> HuffmanCode code;</p><p><b> //字符權(quán)重信息</b></p><p> Static *info;</p><p><b> //字符種數(shù)</
92、b></p><p> int codeSize;</p><p><b> //文件名</b></p><p> char fileName[30];</p><p> int main()</p><p><b> {</b></p><
93、;p> char choice;</p><p> while (true)</p><p><b> {</b></p><p> system("CLS");</p><p> printf(" 赫夫曼編碼加密程序\n");</p><
94、p> Bound('-', 25);</p><p> printf(" 1. 文 件 編 碼 \n");</p><p> printf(" 2. 文 件 譯 碼 \n");</p><p> printf(" 0. 退 出 程 序 \n"
95、);</p><p> Bound('-', 25);</p><p> printf(" 請(qǐng)選擇: ");</p><p> fflush(stdin);</p><p> choice = getchar();</p><p> switch (choice)</
96、p><p><b> {</b></p><p><b> case '1':</b></p><p> FileEncoding();</p><p><b> break;</b></p><p><b> case
97、'2':</b></p><p> FileDecoding();</p><p><b> break;</b></p><p><b> case '0':</b></p><p> printf("\n");</p&
98、gt;<p> system("PAUSE");</p><p><b> return 0;</b></p><p><b> break;</b></p><p><b> default:</b></p><p> printf
99、("\n 您的輸入有誤, 按任意鍵后請(qǐng)從新輸入!");</p><p><b> getch();</b></p><p><b> break;</b></p><p><b> }</b></p><p><b> }</b>
100、;</p><p><b> }</b></p><p> void CreatHuffmanTree(HuffmanTree *&list, Static *info, int codeSize)</p><p><b> {</b></p><p> int i, j, limi
101、t;</p><p> int lnode, rnode;</p><p> int value1, value2;</p><p> HuffmanTree *ptr;</p><p> limit = codeSize * 2 - 1;</p><p> if ((list = (HuffmanTree
102、*)malloc(sizeof(HuffmanTree) * limit)) == NULL)</p><p><b> {</b></p><p> printf(" 內(nèi)存不足, 操作失敗!\n");</p><p><b> exit(0);</b></p><p>&
103、lt;b> }</b></p><p> for(i=0, ptr=list; i<codeSize; ++i, ++ptr)</p><p><b> {</b></p><p> ptr->data = info[i].data;</p><p> ptr->weight
104、 = info[i].weight;</p><p> ptr->parent = ptr->lchild = ptr->rchild = -1;</p><p><b> }</b></p><p> for(; i<limit; ++i, ++ptr)</p><p><b>
105、 {</b></p><p> ptr->data = '0';</p><p> ptr->weight = 0;</p><p> ptr->parent = ptr->lchild = ptr->rchild = -1;</p><p><b> }</
106、b></p><p> for(i=codeSize; i<limit; ++i)</p><p><b> {</b></p><p> value1 = value2 = 32767;</p><p> lnode = rnode = -1;</p><p> for(j
107、=0; j<i; ++j)</p><p><b> {</b></p><p> if (list[j].parent == -1)</p><p><b> {</b></p><p> if (list[j].weight < value1)</p><
108、p><b> {</b></p><p> value2 = value1;</p><p> rnode = lnode;</p><p> value1 = list[j].weight;</p><p> lnode = j;</p><p><b> }<
109、/b></p><p> else if (list[j].weight < value2)</p><p><b> {</b></p><p> value2 = list[j].weight;</p><p> rnode = j;</p><p><b>
110、}</b></p><p><b> }</b></p><p><b> }</b></p><p> list[lnode].parent = i;</p><p> list[rnode].parent = i;</p><p> list[i].
111、weight = list[lnode].weight + list[rnode].weight;</p><p> list[i].lchild = lnode;</p><p> list[i].rchild = rnode;</p><p><b> }</b></p><p><b> }<
112、;/b></p><p> void CreatHuffmanCode(HuffmanTree *list, HuffmanCode &code, int codeSize)</p><p><b> {</b></p><p> int i, start;</p><p> int flag1,
113、flag2; </p><p> char *tempCode;</p><p> if ((code = (char **)malloc(sizeof(char *) * codeSize)) == NULL)</p><p><b> {</b></p><p> printf(" 內(nèi)存不足, 操作
114、失敗!\n");</p><p><b> exit(0);</b></p><p><b> }</b></p><p> if ((tempCode = (char *)malloc(sizeof(char) * codeSize)) == NULL)</p><p><b
115、> {</b></p><p> printf(" 內(nèi)存不足, 操作失敗!\n");</p><p><b> exit(0);</b></p><p><b> }</b></p><p> tempCode[codeSize-1] = '\
116、0';</p><p> for(i=0; i<codeSize; ++i)</p><p><b> {</b></p><p> start = codeSize - 1;</p><p> for(flag1=i, flag2=list[i].parent; flag2 != -1; flag
117、1=flag2, flag2=list[flag2].parent)</p><p><b> {</b></p><p> if (list[flag2].lchild == flag1)</p><p><b> {</b></p><p> tempCode[--start] =
118、39;0';</p><p><b> }</b></p><p><b> else</b></p><p><b> {</b></p><p> tempCode[--start] = '1';</p><p>&l
119、t;b> }</b></p><p><b> }</b></p><p> if ((code[i] = (char *)malloc(sizeof(char) * (codeSize - start))) == NULL)</p><p><b> {</b></p><p
120、> printf(" 內(nèi)存不足, 操作失敗!\n");</p><p><b> exit(0);</b></p><p><b> }</b></p><p> strcpy(code[i], &tempCode[start]);</p><p><
121、b> }</b></p><p> free(tempCode);</p><p><b> }</b></p><p> void DataCount(Static *&info)</p><p><b> {</b></p><p>&
122、lt;b> FILE *fp;</b></p><p><b> char ch;</b></p><p> char choice;</p><p> int characterNumber, typeNumber;</p><p> Data characterList;</p>
123、;<p> Data *ptr, *current, *previous;</p><p> system("CLS");</p><p> printf("\n 請(qǐng)輸入需要打開(kāi)的文件名稱: ");</p><p> fflush(stdin);</p><p> gets(fi
124、leName);</p><p> while ((fp = fopen(fileName, "rb")) == NULL)</p><p><b> {</b></p><p> printf("\n 您需要打開(kāi)的文件不存在, 是否需要重新打開(kāi)(Y/N)? : ");</p><
125、;p> fflush(stdin);</p><p> choice = getchar();</p><p> switch (choice)</p><p><b> {</b></p><p><b> case 'Y':</b></p><
126、p> system("CLS");</p><p> printf("\n 請(qǐng)輸入需要打開(kāi)的文件名稱: ");</p><p> fflush(stdin);</p><p> gets(fileName);</p><p><b> continue;</b>&
127、lt;/p><p><b> case 'N':</b></p><p><b> return;</b></p><p><b> default:</b></p><p><b> break;</b></p><
128、;p><b> }</b></p><p><b> }</b></p><p> characterNumber = typeNumber = 0;</p><p> characterList.next = NULL;</p><p> while ((ch = fgetc(fp
129、)) != EOF)</p><p><b> {</b></p><p> current = characterList.next;</p><p> if (current == NULL)</p><p><b> {</b></p><p> if ((p
130、tr = (Data *)malloc(sizeof(Data))) == NULL)</p><p><b> {</b></p><p> printf(" 內(nèi)存不足, 操作失敗!\n");</p><p><b> exit(0);</b></p><p><b
131、> }</b></p><p> ptr->data = ch;</p><p> ptr->number = 1;</p><p> ptr->next = characterList.next;</p><p> characterList.next = ptr;</p><
132、;p> ++typeNumber;</p><p><b> }</b></p><p><b> else</b></p><p><b> {</b></p><p> while ((current != NULL) && (current
133、->data != ch))</p><p><b> {</b></p><p> previous = current;</p><p> current = current->next;</p><p><b> }</b></p><p> if
134、 (current != NULL)</p><p><b> {</b></p><p> ++(current->number);</p><p> ++characterNumber;</p><p><b> }</b></p><p><b>
135、; else</b></p><p><b> {</b></p><p> if ((ptr = (Data *)malloc(sizeof(Data))) == NULL)</p><p><b> {</b></p><p> printf(" 內(nèi)存不足, 操作
136、失敗!\n");</p><p><b> exit(0);</b></p><p><b> }</b></p><p> ptr->data = ch;</p><p> ptr->number = 1;</p><p> ptr->
137、next = current;</p><p> previous->next = ptr;</p><p> ++typeNumber;</p><p> ++characterNumber;</p><p><b> }</b></p><p><b> }</
138、b></p><p><b> }</b></p><p> fclose(fp);</p><p> codeSize = typeNumber;</p><p> info = (Static *)malloc(sizeof(Static) * codeSize);</p><p&g
139、t; current = characterList.next;</p><p> for (int i=0; i<codeSize; ++i)</p><p><b> {</b></p><p> info[i].data = current->data;</p><p> info[i].we
140、ight = (int)(current->number * 100.0 / characterNumber);</p><p> current = current->next;</p><p><b> }</b></p><p><b> }</b></p><p> vo
141、id FileEncoding()</p><p><b> {</b></p><p> char choice;</p><p> while (true)</p><p><b> {</b></p><p> system("CLS");
142、</p><p> printf(" 文件編碼程序\n");</p><p> Bound('-', 25);</p><p> printf(" 1. 創(chuàng) 建 文 件 編 碼 \n");</p><p> printf(" 2. 導(dǎo) 出 文 件 編 碼 \n
143、");</p><p> printf(" 3. 導(dǎo) 出 文 件 密 鑰 \n");</p><p> printf(" 0. 返 回 主 菜 單 \n");</p><p> Bound('-', 25);</p><p> printf(" 請(qǐng)選擇: &q
144、uot;);</p><p> fflush(stdin);</p><p> choice = getchar();</p><p> switch (choice)</p><p><b> {</b></p><p><b> case '1':</
溫馨提示
- 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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)---- 赫夫曼編碼系統(tǒng)
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)--赫夫曼編碼系統(tǒng)
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì) (赫夫曼編碼)
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)報(bào)告---赫夫曼編碼
- 赫夫曼編碼器數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)實(shí)驗(yàn)報(bào)告(赫夫曼編碼)
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)赫夫曼編碼譯碼器
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)報(bào)告--赫夫曼編碼譯碼器
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)--數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)----huffman編碼
- 數(shù)據(jù)結(jié)構(gòu)前綴編碼課程設(shè)計(jì)
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)---哈夫曼編碼
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)----哈夫曼編碼
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)報(bào)告---前綴編碼問(wèn)題
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)哈夫曼編碼
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)--哈夫曼編碼
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)---哈夫曼編碼
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)哈夫曼編碼
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)--電文編碼譯碼(哈夫曼編碼)
- 數(shù)據(jù)結(jié)構(gòu) 課程設(shè)計(jì)之哈夫曼編碼
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)電文編碼譯碼(哈夫曼編碼)
評(píng)論
0/150
提交評(píng)論