摘要:好久没有写blog,翻译一篇cplusplus上的make heap文档,凑凑数吧。在工程项目中有不少需求是多次求最大数或者最小数,堆是好的选择之一。如果我比较懒,又比较严谨的话,项目也允许使用stl的话,我会采用STL的make_heap, push_heap, pop_heap, sort_heap, 结合vector来完成需求。
- Make heap
template <class RandomAccessIterator>
void make_heap ( RandomAccessIterator first, RandomAccessIterator last );
template <class RandomAccessIterator, class Compare>
void make_heap ( RandomAccessIterator first, RandomAccessIterator last,
Compare comp );
根据随机迭代器first和last指定的范围[first,last)创建一个大顶堆(最大的元素*first在上面,也可以说在容器的front端)。大顶堆的性质是上面的元素总比其两个子节点元素大。在构造堆的过程中,第一个函数使用‘<’进行比较,第二个模板函数使用comp仿函数进行比较。
利用make_heap构造堆后,可以利用vector::push_back配合push_heap把一个元素添加到堆中,利用pop_heap和vector::pop_back删除堆顶的元素(再唠叨句:堆顶元素位于vector的front),仍然得到一个大顶堆。
-
- 例子
// range heap example
#include
#include
#include
using namespace std;
int main () {
int myints[] = {10,20,30,5,15};
vector<int> v(myints,myints+5);
make_heap (v.begin(),v.end());
cout << "initial max heap : " << v.front() << endl;
pop_heap (v.begin(),v.end()); v.pop_back();
cout << "max heap after pop : " << v.front() << endl;
v.push_back(99); push_heap (v.begin(),v.end());
cout << "max heap after push: " << v.front() << endl;
sort_heap (v.begin(),v.end());
cout << "final sorted range :";
for (unsigned i=0; i<v.size(); i++) cout << " " << v[i];
cout << endl;
return 0;
}
-
- 输出:
initial max heap : 30
max heap after pop : 20
max heap after push: 99
final sorted range : 5 10 15 20 99
-
- Complexity
At most, (3*(last-first)) comparisons.
- push_heap
template <class RandomAccessIterator>
void push_heap ( RandomAccessIterator first, RandomAccessIterator last );
template <class RandomAccessIterator, class Compare>
void push_heap ( RandomAccessIterator first, RandomAccessIterator last,
Compare comp );
给定first和last的值,push_heap把last-1这个位置上的元素加入到堆中,最后[first,last)这个范围的元素仍然构成一个堆。
-
- Complexity
At most, log(last-first) comparisons.也就是堆高。从堆底往上调整。如果孩子比父亲大,跟父亲交换位置即可。
- pop_heap
template <class RandomAccessIterator>
void pop_heap ( RandomAccessIterator first, RandomAccessIterator last );
template <class RandomAccessIterator, class Compare>
void pop_heap ( RandomAccessIterator first, RandomAccessIterator last,
Compare comp );
把堆顶的元素移动到last-1的位置,然后调整堆,最后[first,last-1)仍然是一个堆。
-
- Complexity
At most, (2*log(last-first)) comparisons.堆顶元素走了,他的两个儿子比较,谁大谁上来,如此继续比较,直到堆底。因此是2倍的log(last-first)
- sort_heap
template <class RandomAccessIterator>
void sort_heap ( RandomAccessIterator first, RandomAccessIterator last );
template <class RandomAccessIterator, class Compare>
void sort_heap ( RandomAccessIterator first, RandomAccessIterator last,
Compare comp );
调整[first,last)返回的元素,即在容器vector中元素按照升序排列。注意[first,last)这个范围不在具有堆的性质。
-
- Complexity
At most, NlogN comparisons, where N is (last-first).每次把堆顶元素放到vector的last-1, last-2, …,每次move堆顶元素后,都要调整一次堆。