哈夫曼樹與哈夫曼編碼、集合

什么是哈夫曼樹(Huffman Tree)
eg:將百分制的考試成績轉(zhuǎn)換為五分制的成績
if ( score < 60 ) grade = 1;
else if ( score < 70 ) grade = 2;
else if ( score < 80 ) grade = 3;
else if ( score < 90 ) grade = 4;
else grade = 5;
建立判定樹,如果考慮到學(xué)生成績的分布概率,我們發(fā)現(xiàn)得3分和得4分的同學(xué)占了絕大多數(shù)的比例,直接用上述判別流程建立判定樹 顯然效率不夠高。
修改判定樹:
if ( score < 80 )
{
if ( score < 70 )
if ( score < 60 ) grade = 1 ;
else grade = 2 ;
} else if ( score < 90 ) grade = 4 ;
else grade = 5;
按照這種判別流程建立的判定樹 效率得到顯著提高娄昆。
如何根據(jù)結(jié)點不同的查找頻率 構(gòu)造更有效的搜索樹?

-哈夫曼樹的定義

帶權(quán)路徑長度(WPL):設(shè)二叉樹有n個葉子結(jié)點缝彬,每個葉子結(jié)點帶有權(quán)值(即頻率)Wk萌焰,從根結(jié)點到每個葉子結(jié)點的長度為Lk,則每個葉子結(jié)點的帶權(quán)路徑長度之和為 WPL=W1L1+W2L2+ …… +Wn*Ln
目標(biāo):將WPL降到最低谷浅。最優(yōu)二叉樹或哈夫曼樹就是WPL最小的二叉樹

-哈夫曼樹的構(gòu)造:

每次把權(quán)值最小的兩棵二叉樹合并扒俯,得到的新結(jié)點的權(quán)值為兩棵樹的權(quán)值的和,再由新結(jié)點與剩下的結(jié)點中再挑出兩個權(quán)值最小的樹 再次合并一疯,直到最后所有樹連接在一起
如何選取兩個最小的樹撼玄?利用堆
typedef struct TreeNode *HuffmanTree ;
struct TreeNode {
int Weight ;
HuffmanTree Left, Right ;
}
HuffmanTree Huffman ( MinHeap H )
{
// 假設(shè) H -> Size 個權(quán)值已經(jīng)存在 H -> Element [ ]-> Weight 里
int i ; HuffmanTree T ;
BuildMinHeap ( H ) ; // 將 H -> Element [ ]按權(quán)值調(diào)整為最小堆
for ( i = 1 ; i < H -> Size ; i ++ ) { // 做 H -> Size - 1 次合并
T = malloc ( sizeof ( struct TreeNode ) ) ; // 建立新結(jié)點
// 從最小堆中刪除一個結(jié)點 作為新樹的左子結(jié)點
T -> Left = DeleteMin ( H ) ;
// 從最小堆中刪除一個結(jié)點 作為新樹的右子結(jié)點
T -> Right = DeleteMin ( H ) ;
// 計算新權(quán)值
T -> Weight = T -> Left -> Weight + T -> Right -> Weight ;
Insert ( H , T ) ; // 將新樹插入最小堆
}
T = DeleteMin ( H ) ;
return T ;
}
整體復(fù)雜度為 O( N logN )

-哈夫曼樹的特點:

沒有度為1的結(jié)點
n個葉結(jié)點的哈夫曼樹共有2n-1個結(jié)點: n0:葉結(jié)點總數(shù),n1:只有一個兒子的結(jié)點總數(shù)墩邀,n2:有兩個兒子的結(jié)點總數(shù)掌猛; 可知:n2=n0-1;
哈夫曼樹的任意非葉結(jié)點的左右子樹交換后仍是哈夫曼樹眉睹;
對同一組權(quán)值荔茬,存在不同構(gòu)的兩棵哈夫曼樹,不過WPL值是一樣的

-哈夫曼編碼

給定一段字符串竹海,如何對字符串進(jìn)行編碼兔院,可以使得該字符串的編碼存儲空間最少?
假設(shè)有一段文本 包含58個字符站削,并且由以下7個字符構(gòu)成:a,e孵稽,i许起,s,t菩鲜,空格(sp)园细,換行(nl);這7個字符出現(xiàn)的次數(shù)不同接校。如何對這7個字符進(jìn)行編碼 使得總編碼空間最少猛频?
分析:
(1)用等長ASCII編碼:58 x 8=464位狮崩;
(2)用等長3位編碼:58 x 3=174位;(因為只有7個字符鹿寻,3位編碼可編8個字符)
(3)不等長編碼:出現(xiàn)頻率高的字符用的編碼短些睦柴,出現(xiàn)頻率低的字符則可以編碼長些
不等長編碼會長生二義性,如a=1毡熏,e=0坦敌,s=11,t=10痢法;那么編碼1011就會有多種不同意思狱窘,因為我們不知道各個編碼長度具體是多少。
前綴碼(prefix code):任何字符的編碼都不是另一字符編碼的前綴财搁,可以無二義地解碼
用二叉樹進(jìn)行編碼:(1)左右分支:0蘸炸、1 (2)字符只在葉結(jié)點上
只要待編字符在葉結(jié)點上,其二叉樹編碼都不是另一字符編碼的前綴
由哈夫曼樹構(gòu)造一棵編碼代價最小的樹
例:

002WV0d1zy70O2MDV1H55&690.png

-集合的表示:

集合運算:交集尖奔、并集搭儒、補集、差集越锈,判定一個元素是否屬于某一集合
并查集:集合并仗嗦、查某元素屬于什么集合
eg:10臺電腦{1,2甘凭,3稀拐,…,9丹弱,10}已知下列電腦之間已經(jīng)實現(xiàn)了連接:1和2德撬、2和4、3和5躲胳、4和7蜓洪、5和8、6和9坯苹、6和10隆檀,問2和7之間、5和9之間是否是連通的
思路:(1)將10臺電腦看成10個集合(2)已知一種連接“x和y”粹湃,就將x和y對應(yīng)的集合合并(3)查詢“x和y是否是連通的”就是判別x和y是否屬于同一集合恐仑;這種思路就是并查集。
并查集問題中集合存儲的實現(xiàn):
可以用樹結(jié)構(gòu)表示集合为鳄,樹的每一個結(jié)點代表一個集合元素裳仆;雙親表示法:孩子指向雙親
采用數(shù)組存儲形式:data表示元素的值,Parent表示其父結(jié)點的下標(biāo)孤钦,根結(jié)點的Parent用-1表示歧斟;
數(shù)組中每個元素的類型描述為:
typedef struct {
ElementType Data ;
int Parent ; // 每個結(jié)點的父結(jié)點的下標(biāo)
} SetType ;

-集合運算

(1)查找某個元素所在的集合(用根結(jié)點表示)

int Find ( SetType S [ ], ElementType X )
{ // 在數(shù)組 S 中查找值為 X 的元素所屬的集合
// MaxSize 是全局變量纯丸,為數(shù)組 S 的最大長度
int i ;
for ( i = 0 ; i < MaxSize && S [ i ]. Data != X ; i ++ ) ;
if ( i >= MaxSize ) return -1 ; // 未找到X,返回-1
for ( ; S [ i ] . Parent >= 0 ; i = S [ i ] . Parent ) ;
return i ; // 找到X所屬集合静袖,返回樹根結(jié)點在數(shù)組S中的下標(biāo)
}

(2)集合的并運算

分別找到X1和X2兩個元素所在集合樹的根結(jié)點觉鼻,如果它們不同根 則將其中一個根結(jié)點的父結(jié)點指針設(shè)置成另一個根結(jié)點的數(shù)組下標(biāo)。
void Union ( SetType S[ ], ElementType X1 , ElementType X2 )
{
int Root1 , Root2 ;
Root1 = Find ( S , X1 ) ;
Root2 = Find ( S , X2 ) ;
if ( Root != Root2 ) S[ Root2 ] . Parent = Root1 ;
}

這樣并集后勾徽,樹越來越大越來越高滑凉,樹高了之后Find函數(shù)效率會變差,所以盡量把小的集合并到大的集合中去喘帚;用負(fù)數(shù)代表根結(jié)點畅姊,負(fù)數(shù)的絕對值為這棵樹的元素個數(shù)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市吹由,隨后出現(xiàn)的幾起案子若未,更是在濱河造成了極大的恐慌,老刑警劉巖倾鲫,帶你破解...
    沈念sama閱讀 216,470評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件粗合,死亡現(xiàn)場離奇詭異,居然都是意外死亡乌昔,警方通過查閱死者的電腦和手機隙疚,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,393評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來磕道,“玉大人供屉,你說我怎么就攤上這事∧缃叮” “怎么了伶丐?”我有些...
    開封第一講書人閱讀 162,577評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長疯特。 經(jīng)常有香客問我哗魂,道長,這世上最難降的妖魔是什么漓雅? 我笑而不...
    開封第一講書人閱讀 58,176評論 1 292
  • 正文 為了忘掉前任录别,我火速辦了婚禮,結(jié)果婚禮上邻吞,老公的妹妹穿的比我還像新娘庶灿。我一直安慰自己,他們只是感情好吃衅,可當(dāng)我...
    茶點故事閱讀 67,189評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著腾誉,像睡著了一般徘层。 火紅的嫁衣襯著肌膚如雪峻呕。 梳的紋絲不亂的頭發(fā)上吭敢,一...
    開封第一講書人閱讀 51,155評論 1 299
  • 那天茎芭,我揣著相機與錄音,去河邊找鬼乌叶。 笑死跷敬,一個胖子當(dāng)著我的面吹牛讯私,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播西傀,決...
    沈念sama閱讀 40,041評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼斤寇,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了拥褂?” 一聲冷哼從身側(cè)響起娘锁,我...
    開封第一講書人閱讀 38,903評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎饺鹃,沒想到半個月后莫秆,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,319評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡悔详,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,539評論 2 332
  • 正文 我和宋清朗相戀三年镊屎,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片茄螃。...
    茶點故事閱讀 39,703評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡缝驳,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出责蝠,到底是詐尸還是另有隱情党巾,我是刑警寧澤,帶...
    沈念sama閱讀 35,417評論 5 343
  • 正文 年R本政府宣布霜医,位于F島的核電站齿拂,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏肴敛。R本人自食惡果不足惜署海,卻給世界環(huán)境...
    茶點故事閱讀 41,013評論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望医男。 院中可真熱鬧砸狞,春花似錦、人聲如沸镀梭。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,664評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽报账。三九已至研底,卻和暖如春埠偿,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背榜晦。 一陣腳步聲響...
    開封第一講書人閱讀 32,818評論 1 269
  • 我被黑心中介騙來泰國打工冠蒋, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人乾胶。 一個月前我還...
    沈念sama閱讀 47,711評論 2 368
  • 正文 我出身青樓抖剿,卻偏偏與公主長得像,于是被迫代替她去往敵國和親识窿。 傳聞我的和親對象是個殘疾皇子斩郎,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,601評論 2 353

推薦閱讀更多精彩內(nèi)容

  • B樹的定義 一棵m階的B樹滿足下列條件: 樹中每個結(jié)點至多有m個孩子。 除根結(jié)點和葉子結(jié)點外腕扶,其它每個結(jié)點至少有m...
    文檔隨手記閱讀 13,218評論 0 25
  • 課程介紹 先修課:概率統(tǒng)計孽拷,程序設(shè)計實習(xí),集合論與圖論 后續(xù)課:算法分析與設(shè)計半抱,編譯原理脓恕,操作系統(tǒng),數(shù)據(jù)庫概論窿侈,人...
    ShellyWhen閱讀 2,283評論 0 3
  • 這篇文章收錄在我的 Github 上 algorithms-tutorial炼幔,另外記錄了些算法題解,感興趣的可以看...
    Lindz閱讀 8,808評論 1 6
  • 好久沒有更文了史简。 堅持真的不是說一說罷了乃秀。 上個月活動也蠻多的 每天的更文其實更能讓自己認(rèn)清自己, 內(nèi)心也不是那么...
    SU吶閱讀 150評論 0 0
  • 吃過早飯圆兵,趁天涼快跺讯,帶著大寶和二寶去了趟超市。大寶說想喝純奶了殉农,酸奶又喝夠了刀脏。行啊,那就買一箱超凳,畢竟喝奶...
    鄧啟旭鄧君浩媽媽閱讀 133評論 0 1