优先队列特点
- 队列是FIFO(先进先出)
- 优先队列:
- 最大优先队列,不管入队顺序怎么样,都是当前最大的元素优先出队
- 最小优先队列,不管入队顺序怎么样,都是当前最小的元素优先出队
实现方法
- 利用二叉堆的特点
- 入队:放到数组末尾,然后上浮这个节点到合适的位置
- 出队:删除堆顶元素,最后一个补充到堆顶,堆顶元素下沉
- 思考:上浮和下沉的时间复杂度都是O(logn),因此入队和出队的时间复杂度也是O(logn)
代码实现(最大堆为例)
public class PriorityQueue {
private int[] array;
private int size;
public PriorityQueue(){
array = new int[32];
}
public void enQueue(int key) {
if(size >= array.length){
resize();
}
array[size++] = key;
upAdjust();
}
public int deQueue() throws Exception {
if(size <= 0){
throw new Exception("the queue is empty !");
}
int head = array[0];
array[0] = array[--size];
downAdjust();
return head;
}
private void upAdjust() {
int childIndex = size-1;
int parentIndex = (childIndex-1)/2;
int temp = array[childIndex];
while (childIndex > 0 && temp > array[parentIndex])
{
array[childIndex] = array[parentIndex];
childIndex = parentIndex;
parentIndex = (parentIndex-1) / 2;
}
array[childIndex] = temp;
}
private void downAdjust() {
int parentIndex = 0;
int temp = array[parentIndex];
int childIndex = 1;
while (childIndex < size) {
if (childIndex + 1 < size && array[childIndex + 1] > array[childIndex]) {
childIndex++;
}
if (temp >= array[childIndex])
break;
array[parentIndex] = array[childIndex];
parentIndex = childIndex;
childIndex = 2 * childIndex + 1;
}
array[parentIndex] = temp;
}
private void resize() {
int newSize = this.size * 2;
this.array = Arrays.copyOf(this.array, newSize);
}
public static void main(String[] args) throws Exception {
PriorityQueue priorityQueue = new PriorityQueue();
priorityQueue.enQueue(3);
priorityQueue.enQueue(6);
priorityQueue.enQueue(1);
priorityQueue.enQueue(5);
priorityQueue.enQueue(2);
System.out.println("出队元素:" + priorityQueue.deQueue());
System.out.println("出队元素:" + priorityQueue.deQueue());
}
}