当一棵二叉树的每个结点都大于等于他的两个子结点时,称为堆有序。
/**
* 最小堆的实现
*/
public class MinPQ<T extends Comparable<T>>{
private T[] pq; // 位置0是空掉的
private int N = 0; // 堆中元素的个数
// 构造容量为size的堆
public MinPQ(int MAXN) {
pq = (T[])new Comparable[MAXN + 1];
}
// 将元素插入数组的最后,并对这个元素进行上浮操作
public void insert(T key) {
pq[++N] = key;
swim(N);
}
public T getMin() {
if (this.isEmpty()) {
return null;
}
return pq[1];
}
// 将堆中第一个元素与最后一个元素进行交换,然后进行下沉操作
public T delMin() {
if (this.isEmpty()) {
return null;
}
T min = pq[1];
exch(1, N--);
pq[N + 1] = null; // 防止对象游离
sink(1);
return min;
}
public boolean isEmpty() {
return N == 0;
}
public int size() {
return N;
}
// 对索引为k的元素进行上浮操作
private void swim(int k) {
while (k > 1 && less(k, k / 2)) {
exch(k, k / 2);
k /= 2;
}
}
// 对索引为k的元素进行下沉操作
private void sink(int k) {
// 这里要加等于
while (k * 2 <= N) {
int j = k * 2;
// 往值更小的子树走,注意要添加防止越界的限制条件
if (j < N && less(j + 1, j)) {
j++;
}
if (less(k, j)) {
break;
}
exch(k, j);
k = j;
}
}
private void exch(int i, int j) {
T temp = pq[i];
pq[i] = pq[j];
pq[j] = temp;
}
private boolean less(int i, int j) {
return pq[i].compareTo(pq[j]) < 0;
}
}