演算法系列15天速成 第十三 樹操作 下

2021-08-10 03:43:16 字數 4657 閱讀 4313

大家可否知道,檔案壓縮程式裡面的核心結構,核心演算法是什麼?或許你知道,他就運用了赫夫曼樹。

聽說赫夫曼勝過了他的導師,被認為」青出於藍而勝於藍「,這句話也是我比較欣賞的,嘻嘻。

一  概念

了解」赫夫曼樹「之前,幾個必須要知道的專業名詞可要熟練記住啊。

1: 結點的權

「權」就相當於「重要度」,我們形象的用乙個具體的數字來表示,然後通過數字的大小來決定誰重要,誰不重要。

2: 路徑

樹中從「乙個結點"到「另乙個結點「之間的分支。

3: 路徑長度

乙個路徑上的分支數量。

4: 樹的路徑長度

從樹的根節點到每個節點的路徑長度之和。

5: 節點的帶權路徑路勁長度

其實也就是該節點到根結點的路徑長度*該節點的權。

6:   樹的帶權路徑長度

樹中各個葉節點的路徑長度*該葉節點的權的和,常用wpl(weight path length)表示。

二: 構建赫夫曼樹

上面說了那麼多,肯定是為下面做鋪墊,這裡說赫夫曼樹,肯定是要說赫夫曼樹咋好咋好,赫夫曼樹是一種最優二叉樹,

因為他的wpl是最短的,何以見得?我們可以上圖說話。

現在我們做乙個wpl的對比:

圖a: wpl= 5*2 + 7*2 +2*2+13*2=54

圖b:wpl=5*3+2*3+7*2+13*1=48

我們對比一下,圖b的wpl最短的,地球人已不能阻止wpl還能比「圖b」的小,所以,「圖b"就是一顆赫夫曼樹,那麼大家肯定

要問,如何構建一顆赫夫曼樹,還是上圖說話。

第一步: 我們將所有的節點都作為獨根結點。

第二步:   我們將最小的c和a組建為乙個新的二叉樹,權值為左右結點之和。

第三步: 將上一步組建的新節點加入到剩下的節點中,排除上一步組建過的左右子樹,我們選中b組建新的二叉樹,然後取權值。

第四步: 同上。

三: 赫夫曼編碼

大家都知道,字元,漢字,數字在計算機中都是以0,1來表示的,相應的儲存都是有一套編碼方案來支撐的,比如asc碼。

這樣才能在"編碼「和」解碼「的過程中不會成為亂碼,但是asc碼不理想的地方就是等長的,其實我們都想用較少的空間來儲存

更多的東西,那麼我們就要採用」不等長」的編碼方案來儲存,那麼「何為不等長呢「?其實也就是出現次數比較多的字元我們採用短編碼,

出現次數較少的字元我們採用長編碼,恰好,「赫夫曼編碼「就是不等長的編碼。

這裡大家只要掌握赫夫曼樹的編碼規則:左子樹為0,右子樹為1,對應的編碼後的規則是:從根節點到子節點

a: 111

b: 10

c: 110

d: 0

四: 實現

不知道大家懂了沒有,不懂的話多看幾篇,下面說下赫夫曼的具體實現。

第一步:構建赫夫曼樹。

第二步:對赫夫曼樹進行編碼。

第三步:壓縮操作。

第四步:解壓操作。

1:首先看下赫夫曼樹的結構,這裡欄位的含義就不解釋了。

1

#region 赫夫曼樹結構

2///

3///

赫夫曼樹結構

4///

5public

class huffmantree

6 89

public

int parent

1011

public

int left

1213

public

int right

14 }

15#endregion

2: 建立赫夫曼樹,原理在上面已經解釋過了,就是一步一步的向上搭建,這裡要注意的二個性質定理:

當葉子節點為n個,則需要n-1步就能搭建赫夫曼樹。

當葉子節點為n個,則赫夫曼樹的節點總數為:(2*n)-1個。

1

#region 赫夫曼樹的建立

2///

3///

赫夫曼樹的建立

4///

5///

赫夫曼樹

6///

葉子節點

7///

節點權重

8public huffmantree createtree(huffmantree huffman, int leafnum, int weight)

9

20 }

2122

//這裡面也要注意,4個節點,其實只要3步就可以構造赫夫曼樹

23for (int i = leafnum; i < huffmannode; i++)

24

3839

return huffman;

40 }

41#endregion

4243

#region 選出葉子節點中最小的二個節點

44///

45///

選出葉子節點中最小的二個節點

46///

47///

48///

要查詢的結點數

49///

50///

51public

void selectnode(huffmantree huffman, int searchnodes, out

int minindex1, out

int minindex2)

52

7576

//如果為null,則認為當前實體為最小

77if (minnode2 == null)

78

98 }

99if (minnode1 != null && minnode2 != null)

100

111else

112

119 }

120 }

121 }

122 }

123 }

124#endregion

3:對哈夫曼樹進行編碼操作,形成一套「模板」,效果跟asc模板一樣,不過乙個是不等長,乙個是等長。

1

#region 赫夫曼編碼

2///

3///

赫夫曼編碼

4///

5///

6///

7///

8public

string huffmancoding(huffmantree huffman, int leafnum)

9

3839 huffmancode[i] = new

string(codetemp.reverse().toarray());

40 }

41return huffmancode;

42 }

43#endregion

4:模板生成好了,我們就要對指定的測試資料進行壓縮處理

1

#region 對指定字元進行壓縮

2///

3///

對指定字元進行壓縮

4///

5///

6///

7///

8public

string encode(string huffmancode, string alphabet, string test)

9

23 }

24 }

2526

return encodestr;

27 }

28#endregion

5: 最後也就是對壓縮的資料進行還原操作。

1

#region 對指定的二進位制進行解壓

2///

3///

對指定的二進位制進行解壓

4///

5///

6///

7///

8///

9///

10public

string decode(huffmantree huffman, int huffmannodes, string alphabet, string test)

11

25if (test[i].tostring() == "1")

26

29 i++;

30 }

31 decodestr += alphabet[j];

32 }

33return decodestr;

34 }

3536

#endregion

最後上一下總的執行**

view code

基本演算法系列15天速成

演算法系列15天速成 第一天 七大經典排序 上 演算法系列15天速成 第二天 七大經典排序 中 演算法系列15天速成 第三天 七大經典排序 下 演算法系列15天速成 第四天 五大經典查詢 上 演算法系列15天速成 第五天 五大經典查詢 中 演算法系列15天速成 第六天 五大經典查詢 下 演算法系列1...

演算法系列15天速成 第十天 棧

今天跟大家聊聊棧,在程式設計中,棧的使用還是非常廣泛的,比如有 括號匹配問題 html結構匹配問題 所以說掌握了 棧 的使用,對我們學習演算法還是很有幫助的。一 概念 棧,同樣是一種特殊的線性表,是一種last in first out lifo 的形式,現實中有很多這樣的例子,比如 食堂中的一疊盤...

演算法系列15天速成 第十天 棧

今天跟大家聊聊棧,在程式設計中,棧的使用還是非常廣泛的,比如有 括號匹配問題 html結構匹配問題 所以說掌握了 棧 的使用,對我們學習演算法還是很有幫助的。一 概念 棧,同樣是一種特殊的線性表,是一種last in first out lifo 的形式,現實中有很多這樣的例子,比如 食堂中的一疊盤...