大根堆 小根堆 找中位数
2015-01-23 10:07
148 查看
集合中元素,前一半存储在一个最大堆中,后一半存储在一个最小堆中。
使用变量MaxHeapNum记录最大堆元素的个数,使用变量MinHeapNum记录最小堆元素的个数。控制MaxHeapNum与MinHeapNum的差不能超过1。每次将要插入的元素Num与最大堆顶部元素MaxHeapTop和最小堆的顶部元素MinHeapTop将进行比较,根据具体情况进行插入:
1.如果Num < MaxHeapTop,则
1.1 如果MaxHeapNum <= MinHeapNum,将Num插入最大堆;
1.2 如果MaxHeapNum == MinHeapNum + 1,将MaxHeapTop从最大堆中移到最小堆,并将Num插入最大堆。
2.如果MaxHeapTop <= Num <= MinHeapTop,则
2.1 如果MaxHeapNum <= MinHeapNum,将Num插入最大堆;
2.2 如果MaxHeapNum == MinHeapNum + 1,将Num插入最小堆;
3.如果Num > MinHeapTop,则
3.1 如果MinHeapNum <= MaxHeapNum,将Num插入最小堆;
3.2 如果MinHeapNum == MaxHeapNum + 1,将MinHeapTop移到最大堆中,将Num插入最小堆。
在每次插入后,都要根据情况对MaxHeapNum和MinHeapNum进行变更,并将有改动的堆进行堆调整。
上面的插入情况会保证最大堆和最小堆的元素个数差小于1,中位数就只在最大堆和最小堆的顶部元素中产生:如果最大堆和最小堆的元素个数相等,则中位数为最大堆和最小堆的顶部元素的平均值;否则,中位数为元素个数多的那个堆的堆顶元素。
复杂度分析:每次插入元素时的堆调整平均复杂度为O(log(N/2)),插入N次,所以总的复杂度为O(N*log(N/2))。
用一个最大堆存放比中位数小(或等于)的元素,用一个最小堆存放比中位数大(或等于)的元素。这里关键的方法是insert(),每当要插入一个元素时,根据判断条件将它插入最大堆或是最小堆,并更新最大堆和最小堆,使得最大堆和最小堆中元素的个数之差不超过1,这样中位数就是最大堆或最小堆的堆顶元素。当最大堆和最小堆中元素个数不同(个数相差为1)时,元素个数多的那个堆的堆顶元素即为中位数;如果两者元素个数相同,那么中位数可以是最大堆和最小堆的堆顶元素的值取平均。下面的程序代码中,当两者元素个数相同时,将最大堆的堆顶元素看做中位数。
插入(insert) (1)如果最大堆为空,将元素插入最大堆;(2)如果最小堆为空,将元素插入最小堆;(3)如果元素比最大堆的堆顶元素小且最大堆中元素个数不大于最小堆中元素个数,将元素插入最大堆;如果如果元素比最大堆的堆顶元素小但最大堆中元素个数大于最小堆中元素个数,那么先把最大堆的堆顶元素插入最小堆,然后删除最大堆的堆顶元素,最后把元素插入最大堆;(4)如果元素比最小堆的堆顶元素大且最小堆中元素个数不大于最大堆中元素个数,将元素插入最小堆;如果如果元素比最小堆的堆顶元素大但最小堆中元素个数大于最大堆中元素个数,那么先把最小堆的堆顶元素插入最大堆,然后删除最小堆的堆顶元素,最后把元素插入最小堆;(5)如果最大堆中元素个数小于最小堆中元素个数,将元素插入最大堆;否则将元素插入最大堆。
使用变量MaxHeapNum记录最大堆元素的个数,使用变量MinHeapNum记录最小堆元素的个数。控制MaxHeapNum与MinHeapNum的差不能超过1。每次将要插入的元素Num与最大堆顶部元素MaxHeapTop和最小堆的顶部元素MinHeapTop将进行比较,根据具体情况进行插入:
1.如果Num < MaxHeapTop,则
1.1 如果MaxHeapNum <= MinHeapNum,将Num插入最大堆;
1.2 如果MaxHeapNum == MinHeapNum + 1,将MaxHeapTop从最大堆中移到最小堆,并将Num插入最大堆。
2.如果MaxHeapTop <= Num <= MinHeapTop,则
2.1 如果MaxHeapNum <= MinHeapNum,将Num插入最大堆;
2.2 如果MaxHeapNum == MinHeapNum + 1,将Num插入最小堆;
3.如果Num > MinHeapTop,则
3.1 如果MinHeapNum <= MaxHeapNum,将Num插入最小堆;
3.2 如果MinHeapNum == MaxHeapNum + 1,将MinHeapTop移到最大堆中,将Num插入最小堆。
在每次插入后,都要根据情况对MaxHeapNum和MinHeapNum进行变更,并将有改动的堆进行堆调整。
上面的插入情况会保证最大堆和最小堆的元素个数差小于1,中位数就只在最大堆和最小堆的顶部元素中产生:如果最大堆和最小堆的元素个数相等,则中位数为最大堆和最小堆的顶部元素的平均值;否则,中位数为元素个数多的那个堆的堆顶元素。
复杂度分析:每次插入元素时的堆调整平均复杂度为O(log(N/2)),插入N次,所以总的复杂度为O(N*log(N/2))。
用一个最大堆存放比中位数小(或等于)的元素,用一个最小堆存放比中位数大(或等于)的元素。这里关键的方法是insert(),每当要插入一个元素时,根据判断条件将它插入最大堆或是最小堆,并更新最大堆和最小堆,使得最大堆和最小堆中元素的个数之差不超过1,这样中位数就是最大堆或最小堆的堆顶元素。当最大堆和最小堆中元素个数不同(个数相差为1)时,元素个数多的那个堆的堆顶元素即为中位数;如果两者元素个数相同,那么中位数可以是最大堆和最小堆的堆顶元素的值取平均。下面的程序代码中,当两者元素个数相同时,将最大堆的堆顶元素看做中位数。
插入(insert) (1)如果最大堆为空,将元素插入最大堆;(2)如果最小堆为空,将元素插入最小堆;(3)如果元素比最大堆的堆顶元素小且最大堆中元素个数不大于最小堆中元素个数,将元素插入最大堆;如果如果元素比最大堆的堆顶元素小但最大堆中元素个数大于最小堆中元素个数,那么先把最大堆的堆顶元素插入最小堆,然后删除最大堆的堆顶元素,最后把元素插入最大堆;(4)如果元素比最小堆的堆顶元素大且最小堆中元素个数不大于最大堆中元素个数,将元素插入最小堆;如果如果元素比最小堆的堆顶元素大但最小堆中元素个数大于最大堆中元素个数,那么先把最小堆的堆顶元素插入最大堆,然后删除最小堆的堆顶元素,最后把元素插入最小堆;(5)如果最大堆中元素个数小于最小堆中元素个数,将元素插入最大堆;否则将元素插入最大堆。
相关文章推荐
- 找中位数(用堆维持小的一半数,建立大根堆)
- 小根堆,大根堆,堆排序
- CJOJ 2482 【POI2000】促销活动(STL优先队列,大根堆,小根堆)
- 大根堆 小根堆
- 最大堆/最小堆【大根堆/小根堆】
- 大根堆-小根堆-堆排序-C实现
- sort 升序还是降序?priority_queue 大根堆还是小根堆?
- 【2015-2016 ACM-ICPC, NEERC, Northern Subregional Contest G】【脑洞 拓扑排序 大根堆小根堆极限维护】Graph DAG加k边使得最小拓扑序最大
- PriorityQueue 小根堆和大根堆的讨论
- 大根堆,小根堆,堆排序
- 超市market(堆维护,小根堆+大根堆)
- 【每日N题】大根堆、小根堆
- 【数据结构】堆结构小根堆,大根堆,插入,删除等操作的实现
- 堆排序—大根堆,小根堆
- 数据结构 之 堆(完全二叉树、大根堆、小根堆)
- 大根堆和小根堆的C语言实现
- 51nod K 汽油补给 大根堆+小根堆....
- 堆的数据结构能够使得堆顶总是维持最大(对于大根堆)或最小(对于小根堆),给定一个数组,对这个数组进行建堆,则平均复杂度是多少?如果只是用堆的 push 操作,则一个大根堆依次输入 3,7,2,4,1,5,8 后,得到的堆的结构示意图是下述图表中的哪个?
- 用线性时间选择来找无序数组的中位数
- hlg1398邮局问题【找中位数】