标签:ack color turn insert number out 第一个 ber 中间
如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。
使容器左边的数都小于右边的数,即使左右两边的数没有排序,也能根据左边最大的数和右边最小的数来实现查中位数。所以左边用大顶锥实现,右边用小顶锥实现。只需要O(1)的时间就可以实现的到顶锥的数据。
如果数据总数目是偶数,插入小顶锥,否则插入大顶锥。要保证大顶锥中的数字都小于小顶锥中的数字,如果是偶数时,插入小顶锥,如果此时的数据比小顶锥中的数据小,怎么办?
解决:
插入小顶锥时,先把数据插入大顶锥,接着把大顶锥中最大数字拿出来插入小顶锥,最终插入的数字就是原大顶锥中最大的数字,这样就保证了小顶锥中的数字都比大顶锥中的数字大。
插入大顶锥与插入小顶锥类似...
#include <iostream> #include <algorithm> #include <vector> using namespace std; template <typename T> class Solution { public: void insert(T &num); T get_num(); private: vector<T> min;//右边最小堆--第一个数字最小 vector<T> max;//左边最大堆---第一个数字最大 }; template <typename T> void Solution<T>::insert(T &num) { if(((min.size()+max.size())&1)==0)//偶数 { if(max.size()>0&&num<max[0]) { max.push_back(num); push_heap(max.begin(),max.end(),less<T>());//升序 num=max[0]; pop_heap(max.begin(),max.end(),less<T>());//将第一个元素与最以后一个元素替换 max.pop_back();//弹出最后一个元素 } min.push_back(num); push_heap(min.begin(),min.end(),greater<T>());//降序 } else { if(min.size()>0&&min[0]<num) { min.push_back(num); push_heap(min.begin(),min.end(),greater<T>()); num=min[0]; pop_heap(min.begin(),min.end(),greater<T>()); min.pop_back(); } max.push_back(num); push_heap(max.begin(),max.end(),less<T>()); } } template<typename T> T Solution<T>::get_num() { int size=max.size()+min.size(); if(!size) { cerr<<"no number available"<<endl; return 0x3f3f; } int mid=0; if(size&1) return min[0]; else return (min[0]+max[0])/2; } int main() { vector<int> v{1,4,9,7,5,6}; Solution<int> s; for(int i=0;i<v.size();++i) { s.insert(v[i]); } if(s.get_num()!=0x3f3f) cout<<s.get_num()<<endl; else { cerr<<"数组有误."<<endl; return 0; } return 0; }
标签:ack color turn insert number out 第一个 ber 中间
原文地址:https://www.cnblogs.com/tianzeng/p/10236559.html