赫夫曼(Huffman)樹又稱最優(yōu)樹,是1類帶權(quán)路徑長(zhǎng)度最短的樹,有著廣泛的利用。
1 基本概念
① 結(jié)點(diǎn)路徑:從樹中1個(gè)結(jié)點(diǎn)到另外一個(gè)結(jié)點(diǎn)的之間的分支構(gòu)成這兩個(gè)結(jié)點(diǎn)之間的路徑。
② 路徑長(zhǎng)度:結(jié)點(diǎn)路徑上的分支數(shù)目稱為路徑長(zhǎng)度。
③ 樹的路徑長(zhǎng)度:從樹根到每個(gè)結(jié)點(diǎn)的路徑長(zhǎng)度之和。
④ 結(jié)點(diǎn)的帶權(quán)路徑長(zhǎng)度:從樹的根結(jié)點(diǎn)到該結(jié)點(diǎn)的的路徑長(zhǎng)度與結(jié)點(diǎn)的權(quán)(值)的乘積。
權(quán)(值):各種開消、代價(jià)、頻度等的抽象稱呼。
⑤ 樹的帶權(quán)路徑長(zhǎng)度:樹中所有葉子結(jié)點(diǎn)的帶權(quán)路徑長(zhǎng)度之和,記做:
WPL=w1?l1+w2?l2+?+wn?ln=∑wi?li (i=1,2,?,n)
其中:n為葉子結(jié)點(diǎn)的個(gè)數(shù);wi為第i個(gè)結(jié)點(diǎn)的權(quán)值; li為第i個(gè)結(jié)點(diǎn)的路徑長(zhǎng)度。
⑥ Huffman樹:具有n個(gè)葉子結(jié)點(diǎn)(每一個(gè)結(jié)點(diǎn)的權(quán)值為wi) 的2叉樹不止1棵,但在所有的這些2叉樹中,一定存在1棵WPL值最小的樹,稱這棵樹為Huffman樹(或稱最優(yōu)樹) 。
根據(jù)n個(gè)權(quán)值 {w1, w2, ?,wn},構(gòu)造成n棵2叉樹的集合F={T1, T2, ?,Tn},其中每棵2叉樹只有1個(gè)權(quán)值為wi的根結(jié)點(diǎn),沒(méi)有左、右子樹;
② 在F當(dāng)選取兩棵根結(jié)點(diǎn)權(quán)值最小的樹作為左、右子樹構(gòu)造1棵新的2叉樹,且新的2叉樹根結(jié)點(diǎn)權(quán)值為其左、右子樹根結(jié)點(diǎn)的權(quán)值之和;
③ 在F中刪除這兩棵樹,同時(shí)將新得到的樹加入F中;
④ 重復(fù)②、③,直到F只含1顆樹為止。
構(gòu)造Huffman樹時(shí),為了規(guī)范,規(guī)定:
F={T1,T2, ?,Tn}中權(quán)值小的作為新構(gòu)造的2叉樹的左子樹,權(quán)值大的作為右子樹; 在取值相等時(shí),深度小的作為新構(gòu)造的2叉樹的左子樹,深度大的作為右子樹。
例:構(gòu)造權(quán)值集合為W={8, 3, 4, 6, 5, 5}的 Huffman樹。
1 Huffman編碼
在電報(bào)收發(fā)等數(shù)據(jù)通訊中,常需要將傳送的文字轉(zhuǎn)換成由2進(jìn)制字符0、1組成的字符串來(lái)傳輸。為了使收發(fā)的速度提高,就要求電文編碼要盡量地短。
要設(shè)計(jì)長(zhǎng)短不等的編碼,須保證任意字符的編碼都不是另外一個(gè)字符編碼的前綴,這類編碼稱為前綴編碼。
Huffman樹可以用來(lái)構(gòu)造編碼長(zhǎng)度不等且譯碼不產(chǎn)生2義性的編碼。
設(shè)電文中的字符集C={c1,c2, ?,ci, ?,cn},各個(gè)字符出現(xiàn)的次數(shù)或頻度集W={w1,w2, ?,wi, ?,wn}。
Huffman編碼方法
以字符集C作為葉子結(jié)點(diǎn),次數(shù)或頻度集W作為結(jié)點(diǎn)的權(quán)值來(lái)構(gòu)造 Huffman樹。規(guī)定Huffman樹中左分支代表“0”,右分支代表“1” 。
從根結(jié)點(diǎn)到每一個(gè)葉子結(jié)點(diǎn)所經(jīng)歷的路徑分支上的“0”或“1”所組成的字符串,為該結(jié)點(diǎn)所對(duì)應(yīng)的編碼,稱之為Huffman編碼。
由于每一個(gè)字符都是葉子結(jié)點(diǎn),不可能出現(xiàn)在根結(jié)點(diǎn)到其它字符結(jié)點(diǎn)的路徑上,所以1個(gè)字符的Huffman編碼不多是另外一個(gè)字符的Huffman編碼的前綴。
若字符集C={a, b, c, d, e, f}所對(duì)應(yīng)的權(quán)值集合為W={8, 3, 4, 6, 5, 5},如圖6⑵5所示,則字符a,b, c,d, e,f所對(duì)應(yīng)的Huffman編碼分別是:10,010,011,00 ,110,111。
(1) 數(shù)據(jù)結(jié)構(gòu)設(shè)計(jì)
Huffman樹中沒(méi)有度為1的結(jié)點(diǎn),有n個(gè)葉子結(jié)點(diǎn)的Huffman樹共有2n⑴個(gè)結(jié)點(diǎn),則可存儲(chǔ)在大小為2n⑴的1維數(shù)組中。實(shí)現(xiàn)編碼的結(jié)點(diǎn)結(jié)構(gòu)如圖6⑵6所示。
緣由:
◆ 求編碼需從葉子結(jié)點(diǎn)動(dòng)身走1條從葉子到根的路徑;
◆ 譯碼需從根結(jié)點(diǎn)動(dòng)身走1條到葉子結(jié)點(diǎn)的路徑。
結(jié)點(diǎn)類型定義:
#define MAX_NODE 200 /* Max_Node>2n⑴ */
typedef struct
{ char elem; // 待編碼字符
unsigned int Weight ; /* 權(quán)值域 */
unsinged int Parent , Lchild , Rchild ;
} HTNode, *HuffmanTree ;
typedef char **HuffmanCode;
typedef struct Node
{
char elem;
unsigned int m_weight;
}Node; // 字符及其權(quán)值
(2) Huffman樹的生成
算法實(shí)現(xiàn)
待編碼字符的輸入:
cout<<"輸入要編碼字符個(gè)數(shù):" ;
cin>>n;
w=(Node *)malloc(n*sizeof(Node));
cout<<"輸入字符及其對(duì)應(yīng)的權(quán)值:"<<endl;
for(i=0;i<n;i++)
{
cin>>c>>wei;
w[i].elem=c;
w[i].m_weight=wei;
}
從前n個(gè)結(jié)點(diǎn)中,選取權(quán)值比較小的兩個(gè):最小的下標(biāo)為s1,次小的下標(biāo)s2
void Select(HuffmanTree HT,int n,int &s1,int &s2)
{ int i; s1=s2=0;
for(i=1;i<=n;i++)
{ if((HT[i].m_weight<HT[s2].m_weight)&&(HT[i].parent==0)&&(s2!=0))
{ if(HT[i].m_weight<HT[s1].m_weight)
{ s2=s1; s1=i; }
else s2=i;
}
if((s1==0||s2==0)&&HT[i].parent==0)
{ if(s1==0) s1=i;
else if(s2==0)
{ if(HT[i].m_weight<HT[s1].m_weight)
{ s2=s1; s1=i; }
else s2=i;
} // end of else if
} // end of if
} // end of for
return;
}
新結(jié)點(diǎn)的構(gòu)造
for(i=n+1;i<=m;++i)
{
Select((*HT),i-1, s1,s2);
(*HT)[s1].parent=i; (*HT)[s2].parent=i;
(*HT)[i].lchild=s1;
(*HT)[i].rchild=s2;
(*HT)[i].m_weight=(*HT)[s1].m_weight+(*HT)[s2].m_weight;
}
(3) Huffman編碼算法
根據(jù)出現(xiàn)頻度(權(quán)值)Weight,對(duì)葉子結(jié)點(diǎn)的Huffman編碼有兩種方式:
① 從葉子結(jié)點(diǎn)到根逆向處理,求得每一個(gè)葉子結(jié)點(diǎn)對(duì)應(yīng)字符的Huffman編碼。
② 從根結(jié)點(diǎn)開始遍歷整棵2叉樹,求得每一個(gè)葉子結(jié)點(diǎn)對(duì)應(yīng)字符的Huffman編碼。
由Huffman樹的生成知,n個(gè)葉子結(jié)點(diǎn)的樹共有2n⑴個(gè)結(jié)點(diǎn),葉子結(jié)點(diǎn)存儲(chǔ)在數(shù)組HT中的下標(biāo)值為1∽n。
① 編碼是葉子結(jié)點(diǎn)的編碼,只需對(duì)數(shù)組HT[1…n]的n個(gè)權(quán)值進(jìn)行編碼;
② 每一個(gè)字符的編碼不同,但編碼的最大長(zhǎng)度是n。
編碼
(*HC)=(HuffmanCode)malloc(n*sizeof(char*));
cd = (char *)malloc(n*sizeof(char));
cd[n-1]='
主站蜘蛛池模板:
69视频网站|
久久久久在线观看
|
久久精品亚洲精品国产欧美
|
97在线观看视频
|
一级黄色片一级黄色片
|
加勒比不卡视频
|
日韩精品电影在线观看
|
欧美综合第一页
|
欧美亚洲国产一区二区三区
|
日批免费看
|
www.在线播放
|
caoprom超碰
|
日本亚洲最大的色成网站www
|
亚洲国产精品久久久久秋霞不卡
|
国产精品久久久久久久久久久久久久
|
国产精品成
|
亚洲成人二区
|
久久久黄网|
av午夜在线
|
国产视频网
|
欧美一区二区三区电影
|
午夜三区
|
精品粉嫩aⅴ一区二区三区四区
|
俺去俺来也www色官网cms
|
国内久久|
秋霞毛片亚洲午夜精品a
|
黄网免费在线观看
|
国产一区中文字幕
|
在线看中文字幕
|
九九色|
国产视频1|
国产一区二区三区在线
|
日韩一区二区三区在线播放
|
99色综合
|
91麻豆精品一区二区三区
|
欧美在线一区二区三区
|
特级毛片网站
|
亚洲精品动漫久久久久
|
福利视频一区
|
国产伦精品一区二区三区免
|
久久国产精品99精国产
|