priority_queue、自己实现堆调整两种方式,求数据流中的中位数

题目描述如下:
在这里插入图片描述
要求插入的时间复杂度是O(logN),取中位数的时间复杂度是O(1)
想到用优先队列priority_queue,插入时可以动态实现堆的调整

思路:
用大根堆存 <=中位数的那部分数,smallPart,存n/2个
用小根堆存 >= 中位数的那部分数,bigPart,存n/2或n/2+1个

  priority_queue<double> smallPart;//大根堆存储小的那部分
  priority_queue<double,vector<double>,greater<double>> bigPart;//小根堆存储大的那部分

即小根堆要么比大根堆多存一个(小根堆顶即中位数),要么存的一样多(两个堆顶和的平均数)

①当小根堆存的数 多于 大根堆时:应存到大根堆,又因为当前数可能比小根堆的堆顶大,所以先插到小根堆,再将小根堆堆顶pop出来,插到大根堆堆顶

  if(bigPart.size()>smallPart.size()){
   
      bigPart.push(num);
      smallPart.push(bigPart.top());
      bigPart.pop();
  }

②当小根堆存的数 等于 大根堆时:应存到小根根堆,又因为当前数可能比大根堆的堆顶小,所以先插到大根堆,再将大根堆堆顶pop出来,插到小根堆堆顶

  else{
   
      smallPart.push(num);
      bigPart.push(smallPart.top());
      smallPart.pop();
  }

③取的时候就很好判断了:如果小根堆存的比大根堆多,说明奇数个,小根堆堆顶即为中位数;否则偶数个,取两个的平均数

  double findMedian() {
   
      if(bigPart.size()==smallPart.size())
          return (bigPart.top()+smallPart.top())/2;
      else return bigPart.top();
  }

----------------------------------------这是分界线---------------------------------------

上面优先队列的push()、pop()实现了堆的插入、删除后的堆调整,其实也可以自己实现,顺便复习一下堆的知识

①堆的插入:
只能插入到最后一个位置,size++,然后从最后一个非叶子节点开始、向堆顶遍历调整堆

//堆的增加操作,必须是增加在最后一个节点
  void addHeap(vector<int> &input,int newNum){
   
      int i;
      int n=input.size();
      input.push_back(newNum);
      n++;
      
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值