优先队列中Comparator写法总结

PriorityQueue中Comparator的用法首先先看源码中的offer:

public boolean offer(E e) {
        if (e == null)
            throw new NullPointerException();
        modCount++;
        int i = size;
        if (i >= queue.length)
            grow(i + 1);
        size = i + 1;
        if (i == 0)
            queue[0] = e;
        else
            siftUp(i, e);
        return true;
    }

1)if和else,分别执行对象判空和容量判断
2)执行siftUp(i, e),i是原有队列长度,e是要入队的元素。

    private void siftUp(int k, E x) {
        if (comparator != null)
            siftUpUsingComparator(k, x);
        else
            siftUpComparable(k, x);
    }

siftUp是堆中调整元素位置的一种方法,可以看出这里的优先队列是使用最大/最小堆实现的。

观察comparator不为空的情况:

k是原有队列长度,x是要入队的元素,e是父节点(也是最后一个非叶子结点)

    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;
    }

根据源码可以看出如果comparator.compare(x, (E) e)>=0就把x放在队列最后一个位置上,反之则执行元素往上走。

    public static int compare(int x, int y) {
        return (x < y) ? -1 : ((x == y) ? 0 : 1);
    }

也就是说如果x比父节点的值小,x就往上走,这说明这是一个小顶堆。

结合题目:力扣23 合并K个排序链表

public ListNode mergeKLists(ListNode[] lists){
        if(lists.length==0||lists==null) return null;
        PriorityQueue queue=new PriorityQueue<>(lists.length, new Comparator() {
            @Override
            public int compare(ListNode o1, ListNode o2) {
                //要插入的结点值<父节点的值时,说明该结点可以往上走,这是一个小顶堆
                if(o1.val

你可能感兴趣的:(堆排序,算法,数据结构,堆排序)