我试图实现一个允许删除最小值和最大值的优先级队列。我通过在PQ对象中创建两个堆以及另外两个数组来跟踪每个堆中相同值的位置来实现此目的。在执行接收,游泳或交换时,我对如何维护这两个数组感到困惑。
在线,我发现两个数组的比较是[N] = b [ab [N]]和b [N] = a [ba [N]],但问题是我不知道'理解那些方程式。如果有人可以给我一些见解,我想我能够维护阵列。
到目前为止,这是我的代码:
public class MyMinMaxPQ<Key extends Comparable<Key>> {
private int N = 0; // number of items on priority queue
private Key[] a; // minheap
private Key[] b; // maxheap
private int[] ab; // index a to b: a[i] == b[ab[i]]
private int[] ba; // index b to a: b[i] == a[ba[i]]
public MyMinMaxPQ(int maxN) { //constructor
a = (Key[]) new Comparable[maxN+1];
b = (Key[]) new Comparable[maxN+1];
ab = new int[maxN+1];
ba = new int[maxN+1];
}
public Key delMin() {
Key min = b[1];
exch(b, 1, N--);
a[N+1] = null;
sink(a, 1);
return min;
}
public Key delMax() {
Key max = a[1]; // Retrieve max key from top.
exch(a, 1, N--); // Exchange with last item.
a[N+1] = null; // Avoid loitering.
sink(a, 1); // Restore heap property.
return max;
}
public void insert(Key item) {
a[++N] = item;
b[++N] = item;
swim(a, N);
swim(b, N);
a[N] = b[ab[N]];
b[N] = a[ba[N]];
}
private void swim(Key[] heap, int k) {
while (k > 1 && less(heap, k/2, k)) {
exch(heap, k/2, k);
k = k/2;
}
}
/**
* Moves the numbers down the heap
* @param heap the heap that the sink will occur on
* @param k the index number on the heap
*/
private void sink(Key[] heap, int k) {
while (2*k <= N) {
int j = 2*k;
if (j < N && less(heap, j, j+1)) j++;
if (!less(heap, k, j)) break;
exch(heap, k, j);
k = j;
}
}
/**
* @param i = first integer to be compared
* @param j = second integer to be compared
* @return <0 : i precedes j; =0 : i and j are equal; >0 : j precedes i
*/
private boolean less(Key[] heap, int i, int j) {
if (heap == a) {
return a[i].compareTo(a[j]) <= 0;
} else {
return b[i].compareTo(b[j]) >= 0;
}
}
/** exchange the two values at indexes i and j in the same heap */
private void exch(Key[] heap, int i, int j) {
Key t = heap[i];
heap[i] = heap[j];
heap[j] = t;
}
/** Is the priority queue empty? */
public boolean isEmpty() {
return N == 0;
}
/** Return the number of items on the priority queue. */
public int size() {
return N;
}
}