二叉樹的應用 堆排序, 赫夫曼樹

2021-10-10 05:38:28 字數 2853 閱讀 1474

赫夫曼樹

堆排序是利用堆這種資料結構而設計的排序演算法,堆排序是一種選擇排序,最壞、最好、平均時間複雜度均為o(nlogn)

堆是具有以下性質的完全二叉樹:每個節點的值都大於或等於其左右孩子節點的值,稱為大頂堆。不要求節點左右孩子的大小關係。

每個節點的值都小於或等於其左右孩子節點的值,稱為小頂堆。

以大頂堆為例,按層序進行編號,對映到陣列中可以得到arr[i] >= arr[2i+1] arr[i] >= arr[2i+2](i從0開始編號)

一般公升序採用大頂堆,降序採用小頂堆

將待排序序列構造成乙個大頂堆

此時,整個序列的最大值就是堆頂的根節點

將其與末尾元素進行交換,此時末尾就為最大值。

然後將剩餘n-1個元素重新構造成乙個堆,這樣就會得到 n個元素的次小值,如此反覆進行,就能夠得到乙個有序序列了。

找到最後乙個非葉子節點,從此節點開始,從左至右,從下至上進行調整。節點索引: arr.length/2 -1

[注]: 對於最後乙個非葉子節點,有 2n+2 = arr.length,故 n = (arr.length)/2 = arr.length/2 -1

與左右子節點進行比較,構造大頂堆

總結說來就是將堆頂元素和末尾元素進行交換,使末尾元素最大。然後繼續調整堆,獲得第二大的元素,如此反覆交換,重建…

using system;

namespace heapsortdemo

;heapsort

(arr)

;foreach

(var item in arr)

}static

void

heapsort

(int

arr)

for(

int j = arr.length -

1; j >

0; j--

)#region 分步完成

//adjust(arr, 1, arr.length);

//foreach (var item in arr)

////adjust(arr, 0, arr.length);

//foreach (var item in arr)

//#endregion

}///

/// 將 i 對應的非葉子節點調整成大頂堆

///

/// 待調整陣列

/// 非葉子節點在陣列中的索引

/// 對多少個元素進行調整

static

void

adjust

(int

arr,

int i,

int len)

if(arr[k]

> temp)

//如果子節點中最大值大於父節點

else

break;}

//當for迴圈結束後,我們已經將以i為父節點的樹的最大值,放在了最頂部(區域性)

arr[i]

= temp;

//將temp值放到調整後的位置}}

}

給定n個權值作為n個葉子節點,構造一棵二叉樹,若該樹的帶權路徑長度(weighted path length) 達到最小,則稱這樣的二叉樹為最優二叉樹,也成為 huffmantree

赫夫曼樹是帶權路徑長度最短的樹,權值較大的節點離根較近。

路徑和路徑長度: 在一棵樹中,從乙個節點往下可以達到的孩子或孫子節點之間的通路,稱為路徑。通路中分支的數目稱為路徑長度。若規定根節點的層數為1,則從根節點到第l層的路徑長度為l-1

節點的權及帶權路徑長度:若將樹中節點賦給乙個有著某種含義的數值,則這個數值稱為該節點的權。節點的帶權路徑長度為,從根節點到該節點之間的路徑長度與該節點權的乘積。

樹的帶權路徑長度:樹的帶權路徑長度規定為所有葉子節點的帶權路徑長度之和。記為wpl,權值越大的節點離根節點越近的二叉樹才是最優二叉樹,wpl最小的就是赫夫曼樹。

從小到大進行排序,每乙個資料都是乙個節點,每個節點可以看成是一棵最簡單的二叉樹。

取出根節點權值最小的兩棵樹

組成一棵新的二叉樹,該新的二叉樹的根節點的權值是前面兩棵二叉樹根節點權值的和。

將這棵新的二叉樹,以根節點的權值大小再次排序,不斷重複,直至所有資料都被處理。

using system;

using system.collections.generic;

namespace huffmantreedemo

;node root =

createhuffmantree

(arr)

; root.

preorder()

;}static

node

createhuffmantree

(int

arr)

while

(nodes.count >1)

//返回赫夫曼樹的root節點

return nodes[0]

;}}class

node

:icomparable

public

node left

public

node right

public

node

(int

value

)public

override

string

tostring()

]";}public

void

preorder()

//從小到大進行排序

public

intcompareto

(node other)

}}

構造赫夫曼樹(最優二叉樹)

例如,有權值分別為 5 10 15 20 25 40的結點,根據以上演算法構造出乙個哈夫曼樹。取這六個樹中最小的兩個樹5 10連成乙個二叉樹,其權值為15 此時森林裡的樹變為15 5 10 15 20 25 40。取這五個樹中最小的兩個樹 15 5 10 15 構成乙個新的二叉樹30 5 10 15...

赫夫曼樹(最優二叉樹) 赫夫曼編碼

首先我們看一下相關的一些概念。路徑長度 從樹中乙個節點到另外乙個節點之間的分支構成兩個節點之間的路徑,路徑上的分支數目稱為路徑長度。如圖中的數字就為路徑長度。樹的路徑長度就是從樹根到每乙個節點的路徑的長度總和。上圖二叉樹的樹路徑長度為1 1 2 2 2 2 3 3 16。那麼根據這樣可以得出當節點一...

DS二叉樹 赫夫曼樹的構建與編碼

題目描述 給定n個權值,根據這些權值構造huffman樹,並進行huffman編碼 參考課本演算法,注意陣列訪問是從位置1開始 要求 赫夫曼的構建中,預設左孩子權值不大於右孩子權值 輸入 第一行輸入t,表示有t個測試例項 第二行先輸入n,表示第1個例項有n個權值,接著輸入n個權值,權值全是小於1萬的...