c++STL之heap(堆)
1、误区!1、堆排序排完后的堆和大顶堆、小顶堆不是一个概念! 2、heap头文件 3、heap操作的四个函数:
使用建议: 建立堆make_heap(_First,_Last,_Comp) 在堆中添加元素push_heap(_First,_Last,_Comp) max_heap.push_back(15);
push_heap(max_heap.begin(),max_heap.end());
在堆中删除元素pop_heap(_First,_Last,_Comp) pop_heap(max_heap.begin(),max_heap.end());//取出了堆顶元素(也叫删除堆顶元素),放到了底层容器的末尾,原来末尾的元素替代堆顶,end迭代器减1,重新siftdown了堆
max_heap.pop_back();从底层容器(数组或vector)中删除了元素
堆排序sort_heap(_First,_Last,_Comp) 关于堆排序,可以看看这个博客<<白话经典算法系列之七 堆排序>>?https://blog.csdn.net/morewindows/article/details/6709644 4、例1:基本操作的使用底层数据容器:vector #include <iostream> #include <vector> #include <algorithm> using namespace std; void printHeap(vector<int> &v){ for(vector<int>::iterator it= v.begin();it!=v.end();++it){ cout<< *it <<" "; } cout<<"n"<<endl; } int main() { vector<int> min={10,30,1)">22,1)">6,1)">15,1)">9}; 建立小顶堆 make_heap(min.begin(),min.end(),greater<int>()); printHeap(min);6 10 9 30 15 22 插入元素 min.push_back(20); push_heap(min.begin(),greater<int>());该算法前提:必须在堆的条件下 printHeap(min); 6 10 9 30 15 22 20 仍为小顶堆 删除堆顶元素 pop_heap(min.begin(),1)">9 10 20 30 15 22 6 不为小顶堆 这个pop_heap操作后,实际上是把堆顶元素放到了末尾 min.pop_back();这才彻底在底层vector数据容器中删除 printHeap(min);9 10 20 30 15 22 仍为小顶堆 堆排序 保持greater,小顶堆,得到的是降序 sort_heap(min.begin(),1)">试了用less,结果杂乱无章 printHeap(min);30 22 20 15 10 9 注意结果是降序的哦!!!其实是调用了很多次pop_heap(...,greater..),每一次都把小顶堆堆顶的元素往末尾放,没放一次end迭代器减1 return 0; } 2、大顶堆,以及堆排序为升序的例子 4、应用:数据流中的中位数 如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。我们使用Insert()方法读取数据流,使用GetMedian()方法获取当前读取数据的中位数。 class Solution { private: vector<int> max;大顶堆(左部分数据,堆顶为堆的最大值(为max[0])) vector<int> min;小顶堆(右部分数据,堆顶为堆的最小值(为min[0])) public: void Insert( num) { if(((max.size()+min.size())&1)==0)总数偶数 { /*来了一个数,此时总数为偶数,原计划加入到小顶堆,(奇数则到大顶堆,保证两边均匀分配) 但是要保证小顶堆的最小值一直大于大顶堆的最大值(即小顶堆的数大于大顶堆的): if num<大顶堆的最大值: 则反而插入到大顶堆中(大顶堆元素多了1个); 则把大顶堆的最大值删掉,重新插入到小顶堆去; else: 插入元素到小顶堆去。 */ if(max.size()>0 && num< max[]) { 添加num到大顶堆 max.push_back(num); push_heap(max.begin(),max.end(),less<仿函数less保证插入后仍为大顶堆 把大顶堆里的最大值删掉,添加到小顶堆里面去 num= max[]; pop_heap(max.begin(),1)">()); max.pop_back(); min.push_back(num);push_heap前必须push_back到底层容器 push_heap(min.begin(),1)">仿函数greater保证插入后仍为小顶堆 }else { min.push_back(num); 这块,和上面有公共代码,可以化简 push_heap(min.begin(),1)">()); } }总数奇数,原计划送到大顶堆 { if(min.size()>0 && num>min[]) { min.push_back(num); push_heap(min.begin(),1)">()); num=min[]; pop_heap(min.begin(),1)">()); min.pop_back(); max.push_back(num); push_heap(max.begin(),1)">()); } { max.push_back(num); push_heap(max.begin(),1)">()); } } } double GetMedian() { double median=; if((max.size()+min.size())==) ; if(((max.size()+min.size()) &) { median= ((double)max[0]+(double)min[0])/2; } { median= min[]; } return median; } }; ? (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |