序列容器之 heap

2021-08-09 02:38:14 字數 3563 閱讀 4233

heap並不歸屬於stl容器元件,它是個幕後英雄,扮演priority queue ( 4.8節)的助手。顧名思義,priority queue允許使用者以任何次序將任何元素推入容器內,但取出時一定是從優先權最高(也就是數值最高)的元素開始取。binary max heap正是具有這樣的特性,適合作為priority queue的底層機制。

因為優先佇列是每次取優先順序最高的元素。如果低層以list實現,每次需要sort().顯然不現實。而binary search tree則顯得太嚴格,"太重"。而binary heap是個比較合適的選擇。

二叉堆就是一種完全二叉樹。也就是說除了葉子節點以外,是填滿的。並且每個節點都大於或等於子節點的值。

因為這個性質,我們可以使用vector來儲存資料。

把元素放入堆中。首先新放入的元素是在vector的最末尾,然而插入之後未必滿足堆的性質。最大堆中要求,根節點必須的最大的節點。所以尾節點和父節點進行比較,交換,以達到目的。

template

<

class

_randomaccessiterator

>

inline

void

push_heap(_randomaccessiterator

__first, _randomaccessiterator

__last)

template

<

class

_randomaccessiterator, class

_distance, class

_tp>

inline

void

__push_heap_aux(_randomaccessiterator

__first,

_randomaccessiterator

__last, _distance

*, _tp*)​

template

<

class

_randomaccessiterator, class

_distance, class

_tp,

class

_compare

>

void

__push_heap(_randomaccessiterator

__first, _distance

__holeindex,

_distance

__topindex, _tp

__value, _compare

__comp)

*(__first

+__holeindex) =

__value;//把值插入到當前當前位置

}

pop演算法是取最大的元素。取出的時候破壞兩點:

元素的個數-1。

由哪個節點去頂替根節點。

針對第二點,我們從根節點進行下溯,找到最大的節點。

因為當前節點一定大於子節點。所以取較大的節點頂替取出的根節點,並且下溯到根為止。

針對第一點,我們把原本的最後乙個元素放入目前根中的空節點,做一遍push_heap。

元素數量減一。完成工作。

template

<

class

_randomaccessiterator, class

_compare

>

inline

void

pop_heap(_randomaccessiterator

__first,

_randomaccessiterator

__last, _compare

__comp)

​template

<

class

_randomaccessiterator, class

_tp, class

_compare

>

inline

void

__pop_heap_aux(_randomaccessiterator

__first,

_randomaccessiterator

__last, _tp

*, _compare

__comp)

​template

<

class

_randomaccessiterator, class

_tp, class

_distance

>

inline

void

__pop_heap(_randomaccessiterator

__first, _randomaccessiterator

__last,

_randomaccessiterator

__result, _tp

__value, _distance*)​

template

<

class

_randomaccessiterator, class

_distance,

class

_tp, class

_compare

>

void

__adjust_heap(_randomaccessiterator

__first, _distance

__holeindex,

_distance

__len, _tp

__value, _compare

__comp)

//沒有右子節點 只有左子節點的情況 _secondchild < __len

if (__secondchild

==__len)

__push_heap(__first, __holeindex, __topindex, __value, __comp);

}

既然每次pop_heap可獲得heap中鍵值最大的元素,如果持續對整個heap做pop_heap操作,每次將操作範圍從後向前縮減乙個元素.(因為pop_heap會把鍵值最大的元素放在底部容器的最尾端),當整個程式執行完畢時,我們便有了乙個遞增序列。

template

<

class

_randomaccessiterator, class

_compare

>

void

sort_heap(_randomaccessiterator

__first,

_randomaccessiterator

__last, _compare

__comp)

這個演算法用來將一段現有的資料轉化為乙個heap。其主要依據就是4.7.1節提到的complete binary tree的隱式表述(implicit representation)。

template 

void

__make_heap(_randomaccessiterator __first,

_randomaccessiterator __last, _tp*, _distance*)

}

STL序列式容器 heap

stl heap主要有以下幾種操作組成 make heap,建堆 sort heap,堆排序 pop heap,取出堆頂元素 push heap,調整堆 heap並不歸屬於stl容器元件,它是個幕後英雄,扮演priority queue的助手。binary max heap適合作為priority ...

stl之序列容器 deque

相比於vector,deque是一種雙向開口的連續線性空間,可以在頭尾兩端分別做元素的插入和刪除操作。這也決定了其更賦值的容器結構。deque內部維護了start和finish 節點,用於雙端的插入和刪除 map,一塊連續空間,其每個元素都是個指標,指向乙個節點。其指向的節點中有四個元素 cur f...

STL之序列式容器 一 什麼是序列式容器

序列容器以線性序列的方式儲存元素。它沒有對元素進行排序,元素的順序和儲存它們的順序相同。一般來說,有 5 種標準的序列容器,每種容器都具有不同的特性 現在我們來說說序列式容器到底是什麼。所謂序列容器,即以線性排列 類似普通陣列的儲存方式 來儲存某一指定型別 例如 int double 等 的資料,需...