binary_heap
一种完全二叉树
假设array[0]号元素设为无限大或无限小,则某个节点位于array[i]时,它的左孩子节点位于array[2i]处,右孩子节点位于array[2i+1]处,父节点位于array[i/2]处
插入元素:push_heap
首先需要将插入的元素放在vector尾部
进行上溯:与父节点比较,如果父节点小则交换位置,直到不需要对换或到达根节点为止
template <class RandomAccessIterator>
inline void push_heap<RandomAccessIterator first, RandomAccessIterator last) {
__push_heap_aux(first, last, distance_type(first), value_type(first));
}
pop_heap
将根节点与最后一个节点交换
进行下溯:比较根节点与两个孩子,将根节点与最大的孩子交换,直到不需要交换或到达叶节点
template <class RandomAccessIterator>
inline void pop_heap<RandomAccessIterator first, RandomAccessIterator last) {
__pop_heap_aux(first, last,value_type(first));
}
sort_heap
利用pop_heap操作进行排序
template <class RandomAccessIterator>
void sort_heap(RandomAccessIterator first, RandomAccessIterator last) {
while (last - first > 1)
pop_heap(first, last--);
}
make_heap
将现有的数据转化为heap
template <class RandomAccessIterator>
inline void make_heap(RandomAccessIterator first, RandomAccessIterator last) {
__make_heap(first, last, value_type(first), distance_type(first));
}
template <class RandomAccessIterator, class T, class Distance>
void __make_heap(RandomAccessIterator first,
RandomAccessIterator last, T*, Distance*) {
if (last - first < 2) return;
Distance len = last - first;
//第一个需要重排的子树头部
Distance parent = (len - 2) / 2;
while (true) {
__adjust_heap(first, parent, len, T(*(first + parent)));
if (parent == 0) return;
parent--;
}
}
priority_queue
内部为max_heap
template <class T, class Sequence = vector<T>, class Compare = less<typename Sequence::value_type>>
class priority_queue {
public:
typedef ...
protected:
Sequence c;
Compare comp;
public:
...
template <class InputIterator>
priority_queue(InputIterator first, InputIterator last)
: c(first, last) {make_heap(c.begin(), c.end(), comp);}
bool empty();
size_type size();
const_reference top();
void push(const value_type &x) {
__STL_TRY{
c.push_back(x);
push_heap(c.begin(), c.end(), comp);
}
__SL_UNWIND(c.clear());
}
void pop() {
__STL_TRY{
pop_heap(c.begin(), c.end(), comp);
c.pop_back();
}
__SL_UNWIND(c.clear());
}
};