PriorityQueue优先队列实现动态获得最大值和中值

PriorityQueue是可以看成堆中的实例,为了保证一定顺序,PriorityQueue要求要么元素实现Comparable接口,要么传递一个比较器Comparator接口。顺序只在取出的时候保证有序即第一个有序,不保证储存有序!默认构造方法实现的事最小堆即根节点最小。可以重复!(出自《JAVA编程的逻辑》一书375页左右,感觉有用记录下来!)

1.实现最大值代码:

package topK;

import java.util.Collection;
import java.util.PriorityQueue;

public class TopK {
    private PriorityQueue p;
    private int k;

    public TopK(int k) {
        this.p = new PriorityQueue<>(k);
        this.k = k;
    }

    public void addAll(Collection c){
        for(E e:c){
            add(e);
        }
    }

    public void add(E e){
        if (p.size() < k){
            p.add(e);
            return;
        }
        Comparable head = (Comparable) p.peek();
        if (head.compareTo(e) > 0){
//            小于TopK中的最小值,不用变
            return;
        }
//      新元素替换掉原来的最小值称为TopK之一
        p.poll();
        p.add(e);
    }

    public  T[] toArray(T[] a){
        return p.toArray(a);
    }

    public E getKth(){
        return p.peek();
    }
}

使用:

public static void main(String[] args) {
    TopK top5 = new TopK<>(5);
    top5.addAll(Arrays.asList(new Integer[]{
            100,3,4,234,46,75,2,434,47,24,132,67243,435,24355,3,6,3,2,234,67243,435
    }));

    System.out.println(Arrays.toString(top5.toArray(new Integer[0])));
    System.out.println(top5.getKth());
}

2.实现获得中只代码

package midian;

import java.util.Collection;
import java.util.Collections;
import java.util.PriorityQueue;

public class Midian {
    private PriorityQueue minP;
    private PriorityQueue maxP;
//    中值
    private E m;
    public Midian(){
        this.minP = new PriorityQueue<>();
        this.maxP = new PriorityQueue<>(11,Collections.reverseOrder());
    }

    private int compare(E e , E m){
        Comparable  cmpr = (Comparable) e;
        return cmpr.compareTo(m);
    }

    public void add(E e){
//        第一个元素
        if (m == null){
            m = e;
            return;
        }
//小于中值加入最大堆
        if (compare(e , m) <= 0){
            maxP.add(e);
        }else {
            minP.add(e);
        }

        if (minP.size() - maxP.size() >=2){
//            最小堆元素个数多,将m加入最大堆中,然后最小堆中根移除赋值给m
            maxP.add(this.m);
            this.m = minP.poll();
        }else if (maxP.size() - minP.size() >=2){
            minP.add(this.m);
            this.m=maxP.poll();
        }
    }

    public void addAll(Collection c){
        for(E e:c){
            add(e);
        }
    }

    public E getM(){
        return m;
    }
}

使用:

public static void main(String[] args) {
    Midian integerMidian = new Midian<>();
    List list = Arrays.asList(new Integer[] {
            1,2,3,4,5,6,7,8,9,10
    });
    integerMidian.addAll(list);
    System.out.println(integerMidian.getM());
}

你可能感兴趣的:(java)