(1)堆是优先队列的一种实现,核心的方法是swim和sink
(2)堆与二叉查找树不同,堆的父节点比子节点都大
(3)优先队列的应用场合:需要处理有序的元素,但不一定要求他们全部有序,或是不一定要一次就将他们排序
Java实现如下:
/*
* 很简单的最大优先队列,里面存储的是int
*/
public class MaxPQ {
public int N = 0;
public int[] pq = new int[103];
public void sink(int k) {
while(2 * k <= N) {
int j= 2 * k;
if(j < N && pq[j+1] > pq[j]) j++;
if(pq[k] > pq[j]) break;
exch(k, j);
k = j;
}
}
public void swim(int k) {
while(k/2 >= 1 && pq[k] > pq[k/2]) {
exch(k, k/2);
k = k / 2;
}
}
public void insert(int x) {
pq[++N] = x;
swim(N);
}
public int delMax() {
int max = pq[1];
exch(1, N--);
sink(1);
return max;
}
private void exch(int k, int j) {
int temp = pq[j];
pq[j] = pq[k];
pq[k] = temp;
}
}
public class Heap {
public static int[] pq;
public static int N = 0;
public static void sink(int k) {
while(2 * k <= N) {
int j= 2 * k;
if(j < N && pq[j+1] > pq[j]) j++;
if(pq[k] > pq[j]) break;
exch( k, j);
k = j;
}
}
public static void swim(int k) {
while(k/2 >= 1 && pq[k] > pq[k/2]) {
exch(k, k/2);
k = k / 2;
}
}
private static void exch(int k, int j) {
int temp = pq[j];
pq[j] = pq[k];
pq[k] = temp;
}
public static void sort(int[] a) {
pq = a;
N = a.length-1;
for(int i=N/2; i>=1; i--)
sink(i);
while(N > 1) {
exch(1, N--);
// 交换就说明最上面的数已经是最大的了,所以N要先减一
sink(1);
}
}
}