Huffman編碼實驗報告_第1頁
Huffman編碼實驗報告_第2頁
Huffman編碼實驗報告_第3頁
Huffman編碼實驗報告_第4頁
Huffman編碼實驗報告_第5頁
已閱讀5頁,還剩4頁未讀 繼續免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1二進制哈夫曼編碼的原理及步驟(1)信源編碼的計算設有N個碼元組成的離散、無記憶符號集,其中每個符號由一個二進制碼字表示,信源符號個數n、信源的概率分布P={p(si)},i=1,…..,n。且各符號xi的以li個碼元編碼,在變長字編碼時每個符號的平均碼長為;信源熵為:;唯一可譯碼的充要條件:;其中m為碼符號個數,n為信源符號個數,Ki為各碼字長度。構造哈夫曼數示例如下圖所示。1.000000001.000000000.400.600.400.600.300.300.300.3050.150.090.600.090.600.030.030.040.050.030.030.040.05(2)二元霍夫曼編碼規則(1)將信源符號依出現概率遞減順序排序。(2)給兩個概率最小的信源符號各分配一個碼位“0”和“1”,將兩個信源符號合并成一個新符號,并用這兩個最小的概率之和作為新符號的概率,結果得到一個只包含(n-1)個信源符號的新信源。稱為信源的第一次縮減信源,用s1表示。(3)將縮減信源s1的符號仍按概率從大到小順序排列,重復步驟(2),得到只含(n-2)個符號的縮減信源s2。(4)重復上述步驟,直至縮減信源只剩兩個符號為止,此時所剩兩個符號的概率之和必為1,然后從最后一級縮減信源開始,依編碼路徑向前返回,就得到各信源符號所對應的碼字。2功能介紹輸入一段字符序列,通過本程序可得出該字符序列中各個字符出現的次數,以及每個字符出現的概率,并能計算出信源符號熵,每個字符的哈弗曼編碼,和相應的平均碼長,編碼效率,碼方差。3算法基本步驟描述得到信源序列得到信源序列輸出得出信源序列輸出得出信源序列個數得出信源序列的概率輸出計算信源符號熵輸出計算信源符號熵輸出信源符號的哈弗曼編碼輸出信源符號的哈弗曼編碼平均碼長輸出平均碼長輸出輸出編碼效率輸出編碼效率輸出碼方差輸出碼方差4C語言源代碼#include<stdio.h>#include<string.h>#include<math.h>#defineMAX100//定義全局變量h存放信息熵doubleh=0;//定義結構體用于存放信源符號,數目及概率typedefstruct{//不同的字符 charSOURCECODE;//不同字符出現的次數 intNUM;//不同字符出現的概率 doublePROBABILITY;//哈夫曼編碼符號 intCode[MAX]; intstart;//哈夫曼樹的父結點 intparent;//哈夫曼樹的左右子結點 intlchild; intrchild;//哈夫曼編碼的長度 intlengthofhuffmancode;}Hcode;HcodeINFORMATION[MAX];//該函數用來求信源所包含的符號,以及不同符號出現的次數和概率intPofeachsource(charinformationsource[MAX],inta){ inti,j=1,m,flag=0; chartemp;//預先存入第一個字符,便于與后面的字符進行比較//統計不同的字符存入結構體數組中//利用flag標簽來標記每個字符是否出現過,若出現過標記為1,否則置為零 INFORMATION[0].SOURCECODE=informationsource[0]; for(i=1;i<a;i++){ for(m=0;m<i;m++){ flag=0; if(informationsource[m]==informationsource[i]){ flag=1; break; } } if(flag==1) continue; else INFORMATION[j++].SOURCECODE=informationsource[i]; } INFORMATION[j].SOURCECODE='\0'; printf("信源符號數為:%d\n",j);//統計相同的字符出現的次數//每做一個字符出現次數的統計都將結構體數組里的NUM置為零 for(i=0;i<j;i++){ INFORMATION[i].NUM=0; for(m=0;m<a;m++) if(informationsource[m]==INFORMATION[i].SOURCECODE) INFORMATION[i].NUM++; }//統計每個字符出現的概率 for(i=0;i<j;i++) INFORMATION[i].PROBABILITY=(float)INFORMATION[i].NUM/a;//將每個不同字符出現的次數概率都顯示出來 for(i=0;i<j;i++) printf("TheNUMandPROBABILITYofCode'%c'is%dand%.3f\n",INFORMATION[i].SOURCECODE,INFORMATION[i].NUM,INFORMATION[i].PROBABILITY); returnj;}//求信源符號的熵voidH(inta){ inti; for(i=0;i<a;i++){ h+=((-1)*(INFORMATION[i].PROBABILITY)*(log(INFORMATION[i].PROBABILITY)/log(2))); }}//哈夫曼編碼函數voidHuffman(inta){ Hcodecd; inti,j,m=0,lm=0,p,c; doublemin,lmin;//順序初始化每個信源父子結點為-1for(i=0;i<a;i++){INFORMATION[i].parent=-1;INFORMATION[i].lchild=-1;INFORMATION[i].lchild=-1;} //循環構造Huffman樹for(i=0;i<a-1;i++){//min,lmin中存放兩個無父結點且結點權值最小的兩個結點min=lmin=MAX;//找出所有結點中權值最小、無父結點的兩個結點,并合并之為一顆二叉樹for(j=0;j<a+i;j++){if((INFORMATION[j].PROBABILITY<min)&&(INFORMATION[j].parent==-1)){lmin=min;lm=m;min=INFORMATION[j].PROBABILITY;m=j;}elseif((INFORMATION[j].PROBABILITY<lmin)&&(INFORMATION[j].parent==-1)){lmin=INFORMATION[j].PROBABILITY;lm=j;}}//設置找到的兩個子結點m、lm的父結點信息INFORMATION[m].parent=a+i;INFORMATION[lm].parent=a+i;INFORMATION[a+i].PROBABILITY=INFORMATION[m].PROBABILITY+INFORMATION[lm].PROBABILITY; INFORMATION[a+i].parent=-1;INFORMATION[a+i].lchild=m;INFORMATION[a+i].rchild=lm;} for(i=0;i<a;i++){cd.start=a-1;c=i;p=INFORMATION[c].parent;while(p!=-1)/*父結點存在*/{if(INFORMATION[p].lchild==c)cd.Code[cd.start]=1;elsecd.Code[cd.start]=0;cd.start--;/*求編碼的低一位*/c=p;p=INFORMATION[c].parent;/*設置下一循環條件*/}//保存求出的每個葉結點的哈夫曼編碼和編碼的起始位for(j=cd.start+1;j<m;j++){INFORMATION[i].Code[j]=cd.Code[j];}INFORMATION[i].start=cd.start; }}voidmain(){//定義存放信源符號的數組 charinformationsource[MAX]; inti,j,m; doubleaverageofhuffmancode=0.0,Eita,cV=0.0; printf("pleaseinputthesourceofinformation:"); for(i=0;;i++){ scanf("%c",&informationsource[i]); if(informationsource[i]=='\n') break; } informationsource[i]='\0'; printf("信源序列為:");//顯示已輸入的一串信源符號 puts(informationsource);//返回不同信源符號的數目 m=Pofeachsource(informationsource,i);//求信源的符號熵 H(m); printf("信源的符號熵:H(X)=%.3f(比特/符號)\n",h); Huffman(m);//輸出已保存好的所有存在編碼的哈夫曼編碼for(i=0;i<m;i++){printf("%c'sHuffmancodeis:",INFORMATION[i].SOURCECODE);for(j=INFORMATION[i].start+1;j<m;j++)printf("%d",INFORMATION[i].Code[j]); INFORMATION[i].lengthofhuffmancode=m-INFORMATION[i].start-1;printf("\n");}//求哈夫曼編碼的平均碼長和編碼效率 for(i=0;i<m;i++) averageofhuffmancode+=INFORMATION[i].PROBABILITY*INFORMATION[i].lengthofhuffmancode; printf("哈夫曼編碼的平均碼長為:%lf(碼元/信源符號)\n",averageofhuffmancode); Eita=h/averageofhuffmancode; printf("哈夫曼編碼的編碼效率為:%lf\n",Eita);//求哈弗曼編碼的碼方差 for(i=0;i<m;i++) cV+=INFORMATION[i].PROBABILITY*INFORMATION[i].lengthofhuffmancode*INFORMATION[i].lengthofhuffmancode; cV-=averageofhuffmancode*averageofhuffmancode; printf("哈弗曼編碼的碼方差為:%lf\n",cV);}5運行結果截圖:6實驗分析(1)在哈弗曼編碼的過程中,對縮減信源符號按概率有大到小的順序重新排列,應使合并后的新符號盡可能排在靠前的位置,這樣可使合并后的新符號重復編碼次數減少,使短碼得到充分利用。(2)哈弗曼編碼效率相當高,對編碼器的要求也簡單得多。(3)哈弗曼它保證了信源概率大的符號對應于短碼,概率小的符號對應于長碼,每次縮減信源的最后兩個碼字總是最后一位碼元不同,前面的各位碼元都相同,每次縮減信源的最長兩個碼字有相同的碼長。(4)哈弗曼的編法并不一定是唯一的。

溫馨提示

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

評論

0/150

提交評論