今天在写simulator的时候,需要找出M个数中N个最大的数。想起上次和面试官讨论过可以用堆来实现,就查了一下,果然在STL中已经有现成的堆模板。
make_heap
template<class RandomAccessIterator>
void make_heap(RandomAccessIterator first, RandomAccessIterator last);
template<class RandomAccessIterator>
void make_heap(RandomAccessIterator first, RandomAccessIterator last, StrictWeakOrdering comp);
两者的区别在于第二种可自定义比较时一个元素小于另一个元素的定义
简单的例子:
#include <iostream>
#include <algorithm>
using namespace std;
int main(){
int a[10];
for(int i = 0; i != 10; i++)
a[i] = i;
make_heap(a, a + 10);
cout<<a[0]<<endl;
}
输出的堆顶是9,说明构造的是一个最大堆
也可以自己写一个cmp函数,让函数构造一个最小堆
#include <iostream>
#include <algorithm>
using namespace std;
bool cmp(int a, int b){
return a > b;
}
int main(){
int a[10];
for(int i = 0; i != 10; i++)
a[i] = i;
make_heap(a, a + 10, cmp);
cout<<a[0]<<endl;
}
这次堆顶的元素是0
向堆中加入元素:
push_heap
template <class RandomAccessIterator>
void push_heap(RandomAccessIterator first, RandomAccessIterator last);
template <class RandomAccessIterator>
void push_heap(RandomAccessIterator first, RandomAccessIterator last, StrictWeakOrdering comp);
照例是两个版本。函数的结构有点特别:堆以[first, last - 1]表示, 而新增的元素为*(last - 1)
例如:
#include <iostream>
#include <algorithm>
using namespace std;
int main(){
int a[10];
for(int i = 0; i != 10; i++)
a[i] = i;
make_heap(a, a + 9); //用前9个元素构造堆
push_heap(a, a + 10); //将第10个元素加入堆中
cout<<a[0]<<endl;
}
移除堆顶:
pop_heap
template <class RandomAccessIterator>
void pop_heap(RandomAccessIterator first, RandomAccessIterator);
template <class RandomAccessIterator>
void pop_heap(RandomAccessIterator first, RandomAccessIterator, StrictWeakOrdering comp);
照例两个版本。
函数执行后*(last - 1)会被移除(实际上是堆顶元素会被移动到该位置)
优快云的文本功能真是烂