我們前面已經了解過什麼是堆,現在我們來根據它的特徵來研究如何建乙個堆。
初始化,申請空間,給堆賦值
//建立堆的結構體
typedef
struct heap heap;
//初始化堆
void
initheap
(heap* hp,datatype* array,
int size)
hp->capacity = size;
for(
int i =
0; i < size; i++
) hp->size = size;
//調整該二叉樹;使其滿足堆的性質
//找倒數第乙個非葉子節點,開始向下調整,呼叫adjustdown
int leaflast =
((size -2)
>>1)
;for
(; leaflast >=
0;leaflast--)}
//交換
intswap
(int
* a,
int* b)
//向下調整
void
adjustdown
(datatype* array,
int size,
int parent)
if(array[child]
< array[parent]
)else
}}以上,我們的堆已經建成功,如果需要建大堆,我們可以左右孩子中的較大的孩子,與父母做出比較 ,判斷是否需要交換。
那麼如何利用堆的結構實現排序的功能。首先,將n
nn個元素建堆,如果公升序排列建大堆,降序排列建小堆。然後將堆頂元素與最後乙個元素交換,在將剩下的元素重新調整得到滿足堆的新的堆頂元素,重複之前的步驟,每次元素的數量減一。最後,就可以得到我們要求的序列。
//為實現排序調整堆(向下調整)
void
heapadjust
(int
* array,
int size,
int parent)
if(array[child]
< array[parent]
)else}}
//排序
void
heapsort
(int
* array,
int size)
//堆頂元素與最後乙個元素交換,再調整
int end = size -1;
while
(end)
}
時間複雜度:nlo
gnnlog
nlog
n以上,實現了降序的排列方式,若要實現公升序,只需要建立大堆即可。
top k 問題:在n
nn個資料中找最大的或者最小的前k
kk個元素。求最大建小堆,求最小建大堆。(此處以找最大的前k各元素為例)
具體做法:
先遍歷得到前k
kk個元素,建立堆。
用剩下n−k
n-kn−
k個元素與堆頂元素比較,比堆頂大就替換,比堆頂小就丟棄,再調整當前堆, 直到結束,就找到了最大的前k
kk個元素。
時間複雜度nlo
gknlogk
nlog
k
堆 堆排序學習總結
1.堆是什麼?堆是一種特殊的完全二叉樹.其中,堆又分為最大堆和最小堆.最大堆 任一父節點的值都比左右節點的值大.最小堆 任一父節點的值都比左右節點的值小.2.堆排序的過程 a.最小堆公升序排序 最大堆降序排序類似 建立最小堆 儲存根節點的值 或輸出 把最後乙個節點的值儲存到根節點 堆長減 1 調整為...
二叉堆 堆排序
堆排序與快速排序,歸併排序一樣都是時間複雜度為o n logn 的幾種常見排序方法。學習堆排序前,先講解下什麼是資料結構中的二叉堆。二叉堆是完全二叉樹或者是近似完全二叉樹。二叉堆滿足二個特性 1 父結點的鍵值總是大於或等於 小於或等於 任何乙個子節點的鍵值。2 每個結點的左子樹和右子樹都是乙個二叉堆...
二叉堆 堆排序
推薦 某cppblog wutianqi sblog 堆排序實現 include using namespace std 輸出當前堆的排序狀況 void printarray int data,int size 建堆 自底而上地呼叫maxheapify來將乙個陣列a 1.size 變成乙個最大堆 注...