霍夫曼樹 編碼

2021-07-11 16:06:06 字數 3021 閱讀 5201

用陣列儲存二叉樹,fun_encrypt_leaf()由葉子開始至根部編碼,這個儲存編碼串時從尾部開始儲存,對編碼好的字串進行拷貝時正好倒置

過來;fun_encrypt_recursion()從根部開始遞迴到葉子進行編碼;fun_encrypt_onrecurent()非遞迴無棧從根部到葉子進行編碼。思想都很強大,我是碼農— —

bbb……

#include《一坨標頭檔案》  

using namespace std;

#define new pzjay

const

int max=1

<<25;

const

int length=50;//假設每個字母編碼後最長50位

typedef char** hufferman_code;

char *word;

struct node

; void

select(node *ht,int n,int &s1,int &s2)

for(i=1;i<=n;++i)

if(0==ht[i].dad)//dad=0表示未被使用過

if(min_2>ht[i].value && i!=s1)

} void initialize_tree(node *ht,int *w,int n)//初始化霍夫曼樹,加密,構造hufferman樹

for(i=n+1;i<=m;++i)

ht[i].value=ht[i].dad=ht[i].lch=ht[i].rch=0;//以上為初始化過程

printf("下面是構建hufferman樹的過程/n/n");

int s1,s2;//記錄每次取出的兩個頻率最小的結點

for(i=n+1;i<=m;++i)

} void encrypt_leaf(node *ht,hufferman_code &hc,int n)//開始編碼加密---從葉子到根逆向編碼

hc[i]=pzjay char [n-start];//第i個字元的編碼長度為n-start

strcpy(hc[i],cd+start);

//printf("中間 %c: %s/n",word[i],cd);/

} delete cd;

} int cd_len=0;//遞迴函式所用到的全域性變數

void encrypt_recursion(int i,char *cd,node *ht,hufferman_code &hc)//遞迴編碼,傳遞進節點編號i;從根節點開始編碼

else

if(ht[i].rch!=0)//還有右兒子,回退乙個,遍歷之

--cd_len;//

} } void encrypt_onrecurent(node *ht,hufferman_code &hc,int n)//非遞迴無棧編碼

else

if(0==ht[p].rch)

} else

if(ht[p].value==1)//向右走value寫成了rch

} else

} delete cd;

} void printf_hufferman(hufferman_code hc,int n)

} int main()

hufferman_tree=pzjay node[2*n];//先進行位址空間申請,才能傳遞進構造樹的函式

initialize_tree(hufferman_tree,frequency,n);//初始化

//for(int i=2*n-1;i>0;--i)//檢視建好的樹

//printf("%d l=%d r=%d dad=%d/n",i,hufferman_tree[i].lch,hufferman_tree[i].rch,hufferman_tree[i].dad);

encrypt_leaf(hufferman_tree,hc,n);//從葉子開始的編碼

printf("從葉子開始編碼的結果/n");

printf_hufferman(hc,n);//列印編碼後的字元

char *cd=pzjay char[n+5];

encrypt_recursion(2*n-1,cd,hufferman_tree,hc);//遞迴從根開始編碼

printf("從根開始的遞迴編碼的結果/n");

printf_hufferman(hc,n);

delete cd;

encrypt_onrecurent(hufferman_tree,hc,n);//非遞迴無棧編碼

printf("非遞迴無棧編碼的結果/n");

printf_hufferman(hc,n);

return

0;

}

測試資料和編碼結果:

input:

8 a 12

b 3

c 4

e 67

f 56

g 2

h 10

i 100

output:

a: 110

b: 10100

c: 101011

e: 111

f: 1011

g: 101010

h: 100

i: 0

input:

5 a 1

b 2

c 3

d 4

e 5output:

a: 010

b: 011

c: 00

d: 10

e: 11

input:

3 a 1

b 2

c 4output:

a: 00

b: 01

c: 1

ps:根據建樹實現細節的不同,編碼結果可能大同小異,可以無視……可以無視……

霍夫曼編碼

一 八卦 在 演算法為什麼這麼難?這篇部落格裡,劉未鵬講了乙個八卦 根據wikipedia的介紹,霍夫曼同學 當年還在讀ph.d,所以的確是 同學 而這個問題是坑爹的導師robert m.fano 給他們作為大作業的 fano自己和shannon合作給出了乙個suboptimal的編碼方案,為得不到...

霍夫曼編碼

給定乙個文字中出現的一組字元c,每個字元有其出現頻率freq,想構造字元的最優二進位制表示,即用來編碼整個文字的二進位制位最少 定長編碼 每個字元用相同長度的二進位制位數進行編碼,則每個字元的長度n必須滿足,2 n c 變長編碼 思想是賦予高頻字元短碼字,賦予低頻字元長碼字 編碼過程相對簡單,將表示...

霍夫曼編碼

霍夫曼編碼,或者也可以說哈夫曼編碼。它是一種編碼方式,是可變長編碼 vlc 的一種。準確來說,它是一種方法,什麼方法呢?這種方法,它完全依據字元出現的概率來構造異字頭的平均長度最短的碼字。哈夫曼編碼使用變成編碼表對源字元進行編碼,而這個變長編碼表是通過估算源字元出現的概率得到的。它有個特點,就是出現...