二叉堆的應用

2021-09-06 14:19:21 字數 2847 閱讀 1361

有乙個無序陣列,要求你找出陣列中第k大的元素。

給定的無序陣列如下:75

153172

202419

128如果 k=6,也就是要尋找第6大的元素,這個元素是哪乙個呢?

顯然,陣列中第一大的元素是24,第二大的元素是20,第三大的元素是17 … 第6大的元素是9。75

153172

202419

12843

2165

經典的做法:利用小頂堆的特性。

維護乙個容量為k的小頂堆,堆中的k個節點代表著當前最大的k個元素,而堆頂顯然是這k個元素中的最小值。

遍歷原陣列,每遍歷乙個元素,就和堆頂比較,如果當前元素小於等於堆頂,則繼續遍歷;如果元素大於堆頂,則把當前元素放在堆頂位置,並調整二叉堆(下沉操作)。

遍歷結束後,堆頂就是陣列的最大k個元素中的最小值,也就是第k大元素。

假設k=5,具體的執行步驟如下:

1.把陣列的前k個元素構建成堆。

2.繼續遍歷陣列,和堆頂比較,如果小於等於堆頂,則繼續遍歷;如果大於堆頂,則取代堆頂元素並調整堆。

遍歷到元素2,由於 2<3,所以繼續遍歷。

遍歷到元素20,由於 20>3,20取代堆頂位置,並調整堆。

以此類推,我們乙個乙個遍歷元素,當遍歷到最後乙個元素8的時候,小頂堆的情況如下:

此時的堆頂,就是堆中的最小值,也就是陣列中的第k大元素

這個方法的時間複雜度是多少呢?

1.構建堆的時間複雜度是 o(k)

2.遍歷剩餘陣列的時間複雜度是o(n-k)

3.每次調整堆的時間複雜度是 o(logk)

其中2和3是巢狀關係,1和2,3是並列關係,所以總的最壞時間複雜度是o((

n−k)

logk

+k)o((n-k)logk + k)

o((n−k

)log

k+k)

。當k遠小於n的情況下,也可以近似地認為是o(n

logk

)o(nlogk)

o(nlog

k),方法的空間複雜度是o(1

)o(1)

o(1)

public

class

solution

}//3.返回堆頂元素

return array[0]

;}/** * 構建堆

* @param array 待調整的堆

* @param length 堆的有效大小

*/private

static

void

buildheap

(int

array,

int length)

}/**

* 下沉調整

* @param array 待調整的堆

* @param index 要下沉的節點

* @param length 堆的有效大小

*/private

static

void

downadjust

(int

array,

int index,

int length)

// 如果父節點小於任何乙個孩子的值,直接跳出

if(temp <= array[childindex]

)break

;//無需真正交換,單向賦值即可

array[index]

= array[childindex]

; index = childindex;

childindex =

2* childindex +1;

} array[index]

= temp;

}public

static

void

main

(string[

] args)

; system.out.

println

(findnumberk

(array,5)

);}}

此題還有乙個分治法大家都了解快速排序,快速排序利用分治法,每一次把陣列分成較大和較小的兩部分。

我們在尋找第k大元素的時候,也可以利用這個思路,以某個元素a為基準,把大於於a的元素都交換到陣列左邊,小於a的元素都交換到陣列右邊。

比如我們選擇以元素7作為基準,把陣列分成了左側較大,右側較小的兩個區域,交換結果如下:

包括元素7在內的較大元素有8個,但我們的k=5,顯然較大元素的數目過多了。於是我們在較大元素的區域繼續分治,這次以元素12位基準:

這樣一來,包括元素12在內的較大元素有5個,正好和k相等。所以,基準元素12就是我們所求的。

這就是分治法的大體思想,這種方法的時間複雜度甚至優於小頂堆法,可以達到o(n

)o(n)

o(n)。

二叉樹應用 堆

本例中實現了最小堆的構造 插入 刪除。最小堆表示乙個非終端節點均不大於其左右孩子節點。最小堆用完全二叉樹表示,但是二叉樹存入一維陣列中。將完全二叉樹存入陣列,有一些性質。先將二叉樹從上到下,從左到右給每個節點編號0,1.n。那個乙個節點編號i,他的左孩子編號為2 i 1,右孩子編號2 i 2。完全二...

二叉堆在jdk中的應用

二叉堆最核心的操作是上浮和下沉。上浮是新增元素到隊尾元素,然後經過與上一級節點比較,將隊尾元素變動到合適的位置。下沉是頭結點元素,跟左右葉子節點比較,下沉到合適位置。簡單的 實現 public static void buildupheap int arr public static void bu...

二叉堆的實現

include include define max heap size 101 class binaryminheap void insert intvalue void removemin intgetmin void displayheaparray private int heaparray...