用陣列儲存二叉樹,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 的一種。準確來說,它是一種方法,什麼方法呢?這種方法,它完全依據字元出現的概率來構造異字頭的平均長度最短的碼字。哈夫曼編碼使用變成編碼表對源字元進行編碼,而這個變長編碼表是通過估算源字元出現的概率得到的。它有個特點,就是出現...