Priority Queues
1 API和初级实现 API and elementary implementations
//泛型<>,中间是类名,表示声明的MinPQ实例只能储存Transaction类型的值
//MinPQ类:删除最小值
MinPQ<Transaction> pq = new MinPQ<Transaction>();
while (StdIn.hasNextLine()){
String line = StdIn.readLine();
Transaction item = new Transaction(line); //readline自动读取下一行,可见源码
pq.insert(item);
if (pq.size()>M){
pq.delMin();
}
}
- 如果M和N很大,elementary PQ所需时间会很长
- 如果用二叉堆数据结构,时间和空间复杂度俱佳,最接近最优解
- 内容无序需要每次遍历所有元素来寻找最大
- 内容有序,每次需要把大的元素移动一位来插入小的元素,好处在于移除最小项更容易
- 无序数组优先队列的实现:
package Chapter02;
import edu.princeton.cs.algs4.*;
import java.security.Key;
import static com.sun.xml.internal.xsom.impl.UName.comparator;
public class UnorderedMaxPQ<Key extends Comparable<Key>> {
private Key[] pq; //pq[i] = ith element on pq
private int N; //number of elements on pq
public UnorderedMaxPQ(int capacity){
//没有创建泛型数组
pq = (Key[]) new Comparable[capacity];
}
public boolean isEmpty(){
return N == 0;
}
public void insert(Key x){
pq[N++] = x; //输入下一个数据,插入到最末
}
public Key delMax(){
int max = 0;
for (int i = 1; i < N; i++) {
if (less(max,i)) max = i;
}
exch(max,N-1);
return pq[--N];//删除最后一行
}
private void exch(int i, int j) {
Key swap = pq[i];
pq[i] = pq[j];
pq[j] = swap;
}
private boolean less(int i, int j) {
if (comparator == null) {
return ((Comparable<Key>) pq[i]).compareTo(pq[j]) < 0;
}
else {
return comparator.compare(pq[i], pq[j]) < 0;
}
}
}
2 二叉堆 binary heaps
2.1 堆的定义
- 二叉树的每个结点都大于等于它的两个子节点时,它被称为堆有序
- 二叉堆是一组能够用堆有序的完全二叉树排序的元素,并在数组中按照层级储存(不使用数组的第一个位置)
- 在一个堆中,位置k的结点的父结点的位置为k/2,而它的两个子结点的位置分别为2k和2k+1
2.2 堆的算法
2.2.1 由下至上的堆有序化
public class MaxPQ<Key extends Comparable<Key>> {
private Key[] pq; //基于堆的完全二叉树
//堆有序化:上浮
private void swim(int k){
while (k > 1 && less(k/2,k)){
exch(k/2