Java PriorityQueue

PriorityQueue 一個基於優先級的無界優先級隊列。內部使用 Object 數組實現,默認大小是 11

PriorityQueue 通過二叉小頂堆實現,具體說是通過完全二叉樹(complete binary tree)實現的小頂堆(任意一個非葉子節點的權值,都不大於其左右子節點的權值)

優先級隊列的元素按照其自然順序(從小到大)進行排序,或者根據構造隊列時提供的 Comparator 進行排序,具體取決於所使用的構造方法。

PriorityQueue 隊列不允許放入 null,也不允許插入不可比較的對象(沒有實現 Comparable 接口的對象)。

其實可以插入一個沒有實現 Comparable 接口的對象,此時再進行插入就會出現:java.lang.ClassCastException: demos.other.MyNode cannot be cast to java.lang.Comparable
PriorityQueue 隊頭指排序規則最小的那個元素。如果多個元素都是最小值則隨機選一個(待驗證)。
在這裏插入圖片描述
部分源碼如下:

public class PriorityQueue<E> extends AbstractQueue<E>
    implements java.io.Serializable {

    private static final long serialVersionUID = -7720805057305804111L;

    private static final int DEFAULT_INITIAL_CAPACITY = 11;

    transient Object[] queue;

    // The number of elements in the priority queue.
    private int size = 0;

    // The comparator, or null if priority queue uses elements' natural ordering.
    private final Comparator<? super E> comparator;

    transient int modCount = 0;

    public PriorityQueue() {
        this(DEFAULT_INITIAL_CAPACITY, null);
    }

    public PriorityQueue(int initialCapacity) {
        this(initialCapacity, null);
    }

    public PriorityQueue(Comparator<? super E> comparator) {
        this(DEFAULT_INITIAL_CAPACITY, comparator);
    }


    public PriorityQueue(int initialCapacity,Comparator<? super E> comparator) {
        // 實際上不需要至少有一個限制,但可以繼續保持1.5的兼容性
        if (initialCapacity < 1)
            throw new IllegalArgumentException();
        this.queue = new Object[initialCapacity];
        this.comparator = comparator;
    }
}

PriorityQueue 優先級規則可以根據具體需求而定製, 方式有 2 種:

  1. 添加元素自身實現 Comparable 接口,確保元素是可排序的對象。
  2. 添加元素沒有實現 Comparable 接口,可以在創建 PriorityQueue 隊列時直接指定比較器 Comparator。

構造隊列時提供的 Comparator 示例

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

public class PriorityQueueDemo {
    public static void main(String[] args) {
        Comparator<MyNode> comparator = new Comparator<MyNode>() {
            @Override
            public int compare(MyNode o1, MyNode o2) {
                return o1.x - o2.x;
            }
        };
        PriorityQueue<MyNode> queue = new PriorityQueue<>(comparator);
        queue.offer(new MyNode(4));
        queue.offer(new MyNode(8));
        queue.offer(new MyNode(1));
        queue.offer(new MyNode(5));
        queue.offer(new MyNode(7));
        queue.offer(new MyNode(2));
        while (queue.size() != 0) {
            System.out.println(queue.poll());
        }
    }
}

class MyNode {
    int x;

    MyNode(int x) {
        this.x = x;
    }

    @Override
    public String toString() {
        return "MyNode:" + x;
    }
}

輸出:

MyNode:1
MyNode:2
MyNode:4
MyNode:5
MyNode:7
MyNode:8

可排序對象示例

import java.util.PriorityQueue;

public class PriorityQueueDemo {
    public static void main(String[] args) {
        PriorityQueue<MyComparableNode> queue = new PriorityQueue<>();
        queue.offer(new MyComparableNode(4));
        queue.offer(new MyComparableNode(8));
        queue.offer(new MyComparableNode(1));
        queue.offer(new MyComparableNode(5));
        queue.offer(new MyComparableNode(7));
        queue.offer(new MyComparableNode(2));
        while (queue.size() != 0) {
            System.out.println(queue.poll());
        }
    }
}

class MyComparableNode implements Comparable<MyComparableNode> {

    int x;

    MyComparableNode(int x) {
        this.x = x;
    }

    @Override
    public int compareTo(MyComparableNode o) {
        return this.x - o.x;
    }

    @Override
    public String toString() {
        return "MyComparableNode:" + x;
    }
}

輸出:

MyComparableNode:1
MyComparableNode:2
MyComparableNode:4
MyComparableNode:5
MyComparableNode:7
MyComparableNode:8
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章