優先級隊列
一、PriorityQueue
PriorityQueue是優先級隊列,它實現了Queue接口,它的隊列長度
沒有限制,與一般隊列的區別是,它有優先級概念,每個元素都有優先
級,隊頭的元素永遠都是優先級最高的。PriorityQueue內部是用堆實現的。
一、基本用法
主要構造方法:
public PriorityQueue() public PriorityQueue(int initialCapacity, Comparator<? super E> comparator) public PriorityQueue(Collection<? extends E> c) //動態數組大小等於容器中元素的個數
PriorityQueue使用動態數組initialCapacity表示初始數組的大小。舉例:
PriorityQueue<Integer> ints = new PriorityQueue<>(); ints.offer(10); ints.add(28); ints.addAll(Arrays.asList(22, 33, 55, 66)); while (ints.peek() != null) { System.out.println(ints.poll() + " "); }
二、實現原理
內部成員:
private transient Object[] queue; private int size = 0; private final Comparator<? super E> comparator; private transient int modCount = 0;
構造方法:
public PriorityQueue() { this(DEFAULT_INITIAL_CAPACITY, null); } public PriorityQueue(int initialCapacity) { this(initialCapacity, null); } public PriorityQueue(int initialCapacity, Comparator<? super E> comparator) { if(initialCapacity < 1) throw new IllegalArgumentException(); this.queue = new Object[initialCapacity]; this.comparator = comparator; }
添加元素的代碼
public boolean offer(E e) { if(e == null) throw new NullPointerException(); modCount++; int i = size; if(i >= queue.length) //先確保數組長度是否足夠,如果不夠,用grow方法擴展 grow(i + 1); size = i + 1; if(i == 0) //如果是第一次添加 queue[0] = e; else //否則將其放入最后一個位置,並向上調整 siftUp(i, e);return true; }
private void grow(int minCapacity) { int oldCapacity = queue.length; // Double size if small; else grow by 50% int newCapacity = oldCapacity + ((oldCapacity < 64) (oldCapacity + 2) : (oldCapacity >> 1)); // overflow-conscious code if(newCapacity - MAX_ARRAY_SIZE > 0) newCapacity = hugeCapacity(minCapacity); queue = Arrays.copyOf(queue, newCapacity); }
private void siftUp(int k, E x) { if(comparator != null) siftUpUsingComparator(k, x); else siftUpComparable(k, 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; }
查看元素頭部元素:
public E peek() { if(size == 0) return null; return (E) queue[0]; }
刪除頭部元素:略
三、總結
1)實現了優先級隊列,最先出隊的總是優先級最高的,即排序中的第一個。
2)優先級可以有相同的,內部元素不是完全有序的,如果遍歷輸出,除了第一個其他沒有特定順序。、
3)查看頭部元素,入隊出隊的效率都很高
4)根據值查找和刪除元素的效率很低。