您的位置:首页 > 运维架构

make_heap, push_heap, pop_heap, 的使用

2013-03-20 15:12 399 查看


stl make_heap使用

发表于 2012
年 02 月 04 日 由 dllgwgy

摘要:好久没有写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 <iostream>
#include <algorithm>
#include <vector>
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堆顶元素后,都要调整一次堆。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: