您的位置:首页 > 其它

大根堆 小根堆 找中位数

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)如果最大堆中元素个数小于最小堆中元素个数,将元素插入最大堆;否则将元素插入最大堆。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: