[算法]返回中位数

题目

设计一个数据结构,使其能够在接收一个数据流时(数据流全部为整数),动态的返回已经接收到数据的中位数

思路

设计一个大顶堆B,一个小顶堆S,第一个数使其进入B,然后把这个数作为比较的对象,大于这个数使其进入S,小于这个数进入B,每一次进入操作后,执行调整操作,如果两个堆的size之差大于2,进行调整,pop堆顶元素进入另一个堆,这个思路有点像AVL树的思路

实现

package MyExc;

import java.util.Comparator;
import java.util.PriorityQueue;

//大根堆
class MaxIntegerHeap implements Comparator<Integer>{

    @Override
    public int compare(Integer o1, Integer o2) {
        return o2.compareTo(o1);
    }
}


public class MedianHolder {
    private PriorityQueue<Integer> heap1 = new PriorityQueue<>(new MaxIntegerHeap());
    private PriorityQueue<Integer> heap2 = new PriorityQueue<>(/*new MaxIntegerHeap()*/);
    private int com;

    public void push(int data){
        if(heap1.isEmpty()&&heap2.isEmpty()){
            heap1.add(data);
            com = data;
        }else{
            if(data<=com){
                heap1.add(data);
            }else if(data>com){
                heap2.add(data);
            }
        }
        adjust(heap1,heap2);
    }

    private void adjust(PriorityQueue<Integer> heap1, PriorityQueue<Integer> heap2) {
        if(heap1.size()-heap2.size()>1){
            heap2.add(heap1.poll());
        }else if(heap2.size()-heap1.size()>1){
            heap1.add(heap2.poll());
        }
    }

    public float getMedian(){
        if(heap1.size()==heap2.size()){
            return (float)(heap1.poll()+heap2.poll())/2;
        }else if(heap1.size()>heap2.size()){
            return heap1.poll();
        }else{
            return heap2.poll();
        }
    }
}

测试代码

package MyExc;

public class Test {
    @org.junit.Test
    public void run(){
        MedianHolder medianHolder = new MedianHolder();
        medianHolder.push(1);
        medianHolder.push(2);
        medianHolder.push(3);
        medianHolder.push(4);
        medianHolder.push(5);
        medianHolder.push(6);
        medianHolder.push(7);
        medianHolder.push(1000);

        System.out.println(medianHolder.getMedian());
    }
}

改良思路

我目前使用的是第一个数始终作为比较的参照物,似乎动态调节比较合理,把B堆的堆顶作为比较的参照物比较合理

posted @ 2020-02-23 14:43  KrisTse  阅读(230)  评论(0编辑  收藏  举报