# 原来实现优先级队列如此简单

·  阅读 1062

## 队列API定义

``````public interface Queue<T> extends Iterable<T> {
void enqueue(T item); //入队列

T dequeue(); //出队列

int size();

boolean isEmpty();
}

## 初级版本的实现

#### 队列API的抽象类

``````public abstract class AbstractQueue<T> implements Queue<T> {
private Comparator<T> comparator;

public AbstractQueue(Comparator<T> comparator) {
this.comparator = comparator;
}

public boolean less(T a, T b) {
return comparator.compare(a, b) < 0;
}

public void exch(T[] array, int i, int j) {
T tmp = array[i];
array[i] = array[j];
array[j] = tmp;
}
}

#### 基于无序数组实现

``````public class DisorderPriorityQueue<T> extends AbstractQueue<T> {

private T[] queue;
private int size;

public DisorderPriorityQueue(int max, Comparator<T> comparator) {
super(comparator);
this.queue = (T[]) new Object[max];
}

@Override
public void enqueue(T item) {
queue[size++] = item;
}

@Override
public T dequeue() {
int index = 0;
for (int i = 1; i < size; i++) {
if (less(queue[index], queue[i])) {
index = i;
}
}
size--;
exch(queue, index, size);
T data = queue[size];
queue[size] = null;
return data;
}
//省略其他函数
}

#### 基于有序数组实现

``````public class OrderPriorityQueue<T> extends AbstractQueue<T> {

private T[] queue;
private int size;

public OrderPriorityQueue(int max, Comparator<T> comparator) {
super(comparator);
this.queue = (T[]) new Object[max];
}

@Override
public void enqueue(T item) {
queue[size++] = item;
for (int i = size - 1; i > 1 && less(queue[i], queue[i - 1]); i--) {
exch(queue, i, i - 1);
}
}

@Override
public T dequeue() {
size--;
T data = queue[size];
queue[size] = null;
return data;
}

//省略其他函数
}

enqueue时间复杂度是O(n)，dequeue时间复杂度是O(1)

## 二叉堆实现

#### 由上向下恢复堆有序（上浮）

``````private void swim(int k) {
while (k > 0 && less(queue[k / 2], queue[k])) {
exch(queue, k / 2, k);
k = k / 2;
}
}

#### 由下向上恢复堆有序（下沉）

``````private void sink(int k) {
while (2 * k <= size) {
int i = 2 * k;
if (less(queue[i], queue[i + 1])) {
i++;
}
if (less(queue[i], queue[k])) {
break;
}
exch(queue, i, k);
k = i;
}
}

#### 二叉堆实现优先级队列

• 入队操作：将新的元素添加到数组末尾，让新元素上浮到适合位置，增加堆的大小
• 出队操作：将最大的根节点删除，然后把最后一个元素放入到顶端，下层顶端元素到合适位置，减小堆大小
``````public class BinaryHeapPriorityQueue<T> extends AbstractQueue<T> {
private T[] queue;
private int size;

public BinaryHeapPriorityQueue(int max, Comparator<T> comparator) {
super(comparator);
this.queue = (T[]) new Object[max + 1];
}

@Override
public void enqueue(T item) {
this.queue[++size] = item;
this.swim(size);
}

@Override
public T dequeue() {
T max = this.queue[1];
exch(this.queue, 1, size--);
this.queue[size + 1] = null; //释放内存
this.sink(1);
return max;
}

//省略其他函数
}