PriorityQueue如何确定构建的是大根堆还是小根堆

PriorityQueue可以自定义传入的Comparator来比较内部元素的大小,Comparator比较时的返回如下:

        如果o1 == o2 ,返回0

        如果o1 < o2 ,即 o1-o2 < 0 ,则返回负数

        如果o1 > o2 ,即 o1-o2 > 0 ,则返回正数

PriorityQueue如何确定构建的是大根堆还是小根堆_第1张图片

        如下是PriorityQueue类中新放入元素时执行的代码,x是新放入的元素,k是队列大小,这里只要关注x就好了。可以看到满足 comparator.compare(x, (E) e) >= 0 时会跳出循环,e是队列中原先就存在的元素,即输入的x停止继续往堆顶上升

    private void siftUpUsingComparator(int k, E x) {
        while (k > 0) {
            int parent = (k - 1) >>> 1;
            Object e = queue[parent];
            if (comparator.compare(x, (E) e) >= 0)
                break;
            queue[k] = e;
            k = parent;
        }
        queue[k] = x;
    }

所以当使用如下自定义比较器时,o1对应x(输入的元素),o2对应e(队列中原有的元素):

new PriorityQueue<>(k, new Comparator() {
    @Override
    public int compare(Integer o1, Integer o2) {
        return o1 - o2; 
    }
})

此时如果o1-o2>=0,即x>=e时,x会停止往堆顶上升。否则如果o1-o2<0,即x

代码换一下,变成o2-o1。此时如果o2-o1>=0,即e>=x时,x会停止往堆顶上升。否则如果o2-o1>=0,即e

new PriorityQueue<>(k, new Comparator() {
    @Override
    public int compare(Integer o1, Integer o2) {
        return o2 - o1; 
    }
})

总结下就是,比较器比较o1 和 o2时,如果o1比较大,o1比较大会停止继续往堆顶上升,此时就是最小堆;如果o1比较小,那就是最大堆。

你可能感兴趣的:(JAVA8-集合类源码,java)