堆 Heap 的相關知識學習

2021-10-25 03:41:58 字數 3316 閱讀 3418

堆邏輯上是一棵完全二叉樹

堆物理上是儲存在陣列中

滿足任意結點的值都大於其子樹中結點的值,叫做大堆,或者大根堆,或者最大堆

反之,則是小堆,或者小根堆,或者最小堆

(1)向下調整

過程(以小堆為例):

index 如果已經是葉子結點,則整個調整過程結束

判斷 index 位置有沒有孩子

因為堆是完全二叉樹,沒有左孩子就一定沒有右孩子,所以判斷是否有左孩子

因為堆的儲存結構是陣列,所以判斷是否有左孩子即判斷左孩子下標是否越界,即 left >= size 越界

確定 left 或 right,誰是 index 的最小孩子 min

如果右孩子不存在,則 min = left

否則,比較 array[left] 和 array[right] 值得大小,選擇小的為 min

比較 array[index] 的值 和 array[min] 的值,如果 array[index] <= array[min],則滿足堆的性質,調整結束

否則,交換 array[index] 和 array[min] 的值

然後因為 min 位置的堆的性質可能被破壞,所以把 min 視作 index,向下重複以上過程

**實現:

public

static

void

adjustdown

(int

array,

int size,

int index)

// 2. 找最小的孩子

int minindex = leftindex;

int rightindex = leftindex +1;

if(rightindex < size && array[rightindex]

< array[leftindex]

)// 3. 比較最小孩子的值 和 index 位置的值

if(array[index]

<= array[minindex]

)// 4. 交換

int t = array[index]

; array[index]

= array[minindex]

; array[minindex]

= t;

// 5. 把最小的孩子視為 index,繼續迴圈

index = minindex;

}}

(2)建堆

過程:我們給出乙個陣列,這個陣列邏輯上可以看做一顆完全二叉樹,但是還不是乙個堆,現在我們通過演算法,把它構建成乙個堆。根節點左右子樹不是堆,我們怎麼調整呢?這裡我們從倒數的第乙個非葉子節點的子樹開始調整,一直調整到根節點的樹,就可以調整成堆。

**實現:

public

static

void

createheap

(int

array,

int size)

}

優先順序佇列

概念:在很多應用中,我們通常需要按照優先順序情況對待處理物件進行處理,比如首先處理優先順序最高的物件,然後處理次高的物件。最簡單的乙個例子就是,在手機上玩遊戲的時候,如果有來電,那麼系統應該優先處理打進來的**。在這種情況下,我們的資料結構應該提供兩個最基本的操作,乙個是返回最高優先順序物件,乙個是新增新的物件。這種資料結構就是優先順序佇列(priority queue)

操作:一、 入佇列:

首先按尾插方式放入陣列

比較其和其雙親的值的大小,如果雙親的值大,則滿足堆的性質,插入結束

否則,交換其和雙親位置的值,重新進行 2、3 步驟

直到根結點

二、出佇列:

為了防止破壞堆的結構,刪除時並不是直接將堆頂元素刪除,而是用陣列的最後乙個元素替換堆頂元素,然後通過向下調整方式重新調整成堆

三、返回隊首元素

**實現如下:

public

class

mypriorityqueue

public integer element()

return array[0]

;}// o(log(n))

public integer remove()

int e = array[0]

; array[0]

= array[size -1]

; size--

;adjustdown(0

);return e;

}// o(log(n))

public

void

add(integer e)

private

void

adjustup

(int index)

// 2. 找到 index 的父節點

int parentindex =

(index -1)

/2;// 3. 比較 父節點的值 和 index 的值

// 4. 只要父節點的值 <= index 的值,調整結束

if(array[parentindex]

<= array[index]

)// 5. 交換 父節點 和 index 位置的值

int t = array[index]

; array[index]

= array[parentindex]

; array[parentindex]

= t;

// 6. 把 父節點看作 index,繼續這個大迴圈

index = parentindex;}}

private

void

adjustdown

(int index)

int rightindex = leftindex +1;

int minindex = leftindex;

if(rightindex < size && array[rightindex]

< array[leftindex])if

(array[index]

<= array[minindex]

)int t = array[index]

; array[index]

= array[minindex]

; array[minindex]

= t;

index = minindex;}}

}

堆(Heap)的實現

這次實現了堆,這個堆不是指系統堆疊的堆,是一種資料結構,見下圖 堆的本質就是乙個陣列 上圖中,紅色的是值,黑色的是下標 簡單的來說就是把乙個陣列看成是二叉樹,就像上圖 大堆和小堆分別是指根節點比孩子節點的值大或者是小,看了上圖之後就可以發現,父親節點和孩子節點之間下表的關係,parnet child...

堆 Heap 的實現

什麼是堆?優先佇列 opriority queue 特殊的 佇列 取出元素的順序是依照元素的優先權 關鍵字 大小,而不是元素進入佇列的先後順序。堆有兩大特性 1,結構性 是一顆完全二叉樹。2,有序性 每個葉子結點到根結點都是有序的,如果是公升序,那麼就是最大堆,否則為最小堆。這些是堆 下面的不是堆 ...

堆(Heap)的實現

這次實現了堆,這個堆不是指系統堆疊的堆,是一種資料結構,見下圖 堆的本質就是乙個陣列 上圖中,紅色的是值,黑色的是下標 簡單的來說就是把乙個陣列看成是二叉樹,就像上圖 大堆和小堆分別是指根節點比孩子節點的值大或者是小,看了上圖之後就可以發現,父親節點和孩子節點之間下表的關係,parnet child...