1. 优先级队列概念
提供两个最基本的操作,一个是返回最高优先级对象,一个是添加新的对象,这种数据结构就是优先级队列(Priority Queue)。
2. Java 提供的优先级队列
Java 框架提供了 Priority Queue 和 PriorityBlocking Queue 两种类型的优先级队列,前者是线程不安全的,后者是线程安全的。
关于 Priority Queue 的使用要注意:
- Priority Queue 中放置的元素必须要能够比较大小,不能插入无法比较大小的对象,否则会抛出 ClassCastExceoption 异常;
- 不能插入 null 对象,否则会抛出 NullPointerException;
- 没有容量限制,可以插入任意多个元素,其内部会自动扩容;
- 插入和删除元素的时间复杂度是 o(log(2n));
- Priority Queue 底层使用了堆数据结构。
3. 优先级队列的模拟实现
import java.util.Comparator;
public class MyPriorityQueue {
// 不考虑扩容
private String[] array = new String[100];
private int size = 0;
private Comparator<String> comparator;
public MyPriorityQueue(){
this.comparator = null;
}
public MyPriorityQueue(Comparator<String> comparator){
this.comparator = comparator;
}
public void add(String e){
array[size++] = e;
shiftUp(size - 1);
}
public String remove(){
String e = array[0];
array[0] = array[size - 1];
size--;
shiftDown(0);
return e;
}
public String element(){
return array[0];
}
private void shiftUp(int index) {
while (index > 0){
int parentIndex = (index - 1) / 2;
int r = compare(index, parentIndex);
if (r <= 0){
return;
}
String t = array[index];
array[index] = array[parentIndex];
array[parentIndex] = t;
index = parentIndex;
}
}
private void shiftDown(int index) {
while (true){
int leftIndex = 2 * index + 1;
if (leftIndex >= size){
return;
}
int minIndex = leftIndex;
int rightIndex = leftIndex + 1;
if (rightIndex < size){
int r = compare(leftIndex, rightIndex);
if (r < 0){
minIndex = rightIndex;
}
}
int r = compare(minIndex, index);
if (r <= 0){
return;
}
String t = array[index];
array[index] = array[minIndex];
array[minIndex] = t;
index = minIndex;
}
}
private int compare(int i, int j) {
int r;
if (comparator != null){
r = comparator.compare(array[j], array[i]);
}else {
r = array[j].compareTo(array[i]);
}
return r;
}
}