堆與堆排序

2021-10-06 07:04:43 字數 2166 閱讀 5422

大根堆與小根堆必須是完全二叉樹

大根堆的父節點永遠比子節點大或相等

小根堆的父節點永遠比子節點小或相等

本文皆以大根堆為例

尾部增加元素

調整為大根堆:與父節點比對,若大於父節點則交換位置,直到小於等於父節點或沒有父節點時停止

void

push

(int value)

void

heapinsert

(int

arr,

int i)

}

時間複雜度:o(logn) 空間複雜度:o(1)

根節點與尾節點交換,刪除尾節點

調整為大根堆:根節點與子節點比較,與比他大的最大子節點交換,直到無子節點比父子節點大,或孩子不存在時結束

int

pop(

)void

heapify

(int

arr,

int index,

int heapsize)

swap

(arr, win, index)

; index = win;

left = index *2+

1;}}

時間複雜度:o(logn) 空間複雜度:o(1)

從上往下建堆

void

heapsort

(int

arr)

int heapsize = arr.length;

while

(heapsize >0)

}

時間複雜度:o(nlogn),空間複雜度:o(1)

從下往上建堆

void

heapsort

(int

arr)

while

(heapsize >0)

}

時間複雜度:o(nlogn),空間複雜度:o(1)

改進版與標準版同為o(nlogn),到底快在哪兒?快在建堆

標準版是從上往下建堆,o(nlogn)

第1層,1個節點,操作1次(看自己一眼,沒法往上公升)

第2層,2個節點,操作2次 (看自己一眼,上公升1次)

…第n-2層,2^(n-3)個節點,操作n-2次(看自己一眼,上公升n-3次)

第n-1層,2^(n-2)個節點,操作n-1次(看自己一眼,上公升n-2次)

第n層,2^(n-1)個節點,操作n次(看自己一眼,上公升n-1次)

改進版是從下往上建堆,o(n)

第1層,1個節點,操作n次(看自己一眼,下沉n-1次)

第2層,2個節點,操作n-1次 (看自己一眼,下沉n-2次)

…第n-2層,2^(n-3)個節點,操作3次(看自己一眼,下沉2次)

第n-1層,2^(n-2)個節點,操作2次(看自己一眼,下沉1次)

第n層,2^(n-1)個節點,操作1次(看自己一眼,沒子節點,沒法沉)

堆其實就是個完全二叉樹,那麼最底層元素通常佔了一半,於是越底層的交換成本越高,則整體建堆成本越高

例:[2, 3, 1, 4, 6, 5, 9, 7, 8],移動不超過3

解先搞乙個k+1的小根堆,將k+1個元素push進去

當陣列還有元素時,每pop乙個就往裡push乙個

直到小根堆pop空

void

sortedarrdistancelessk

(int

arr,

int k)

priorityqueue

heap =

newpriorityqueue

<

>()

;// 預設為小根堆

int index =0;

for(

; index <= math.

min(arr.length -

1, k)

; index++

)int i =0;

for(

; index < arr.length; i++

, index++

)while

(!heap.

isempty()

)}

堆與堆排序

二叉堆是完全二叉樹或者是近似完全二叉樹。二叉堆滿足二個特性 1 父結點的鍵值總是大於或等於 小於或等於 任何乙個子節點的鍵值。2 每個結點的左子樹和右子樹都是乙個二叉堆 都是最大堆或最小堆 當父結點的鍵值總是大於或等於任何乙個子節點的鍵值時為最大堆。當父結點的鍵值總是小於或等於任何乙個子節點的鍵值時...

堆與堆排序

堆排序與快速排序,歸併排序一樣都是時間複雜度為o n logn 的幾種常見排序方法。堆排序是就地排序,輔助空間為o 1 它是不穩定的排序方法。排序的穩定性是指如果在排序的序列中,存在前後相同的兩個元素的話,排序前 和排序後他們的相對位置不發生變化 先說說什麼是堆,堆通常是乙個可以被看做一棵樹的陣列物...

堆與堆排序

堆排序與快速排序,歸併排序一樣都是時間複雜度為o n logn 的幾種常見排序方法。學習堆排序前,先講解下什麼是資料結構中的二叉堆。二叉堆是完全二叉樹或者是近似完全二叉樹。二叉堆滿足二個特性 1 父結點的鍵值總是大於或等於 小於或等於 任何乙個子節點的鍵值。2 每個結點的左子樹和右子樹都是乙個二叉堆...