我正在研究优先级队列(堆)并认为我有一个良好的基础。我认为我的方法在大多数情况下都有意义但在我的bubbleDown
和deleteMin
方法上真的很难。
public class Heap {
private int n;
private Node[] s;
public Heap() {
s = new Node[128];
n =0;
}
public boolean isEmptySet() {
return (n == 0);
}
public Node findMin() {
return s[0];
}
public void insert(Node p) {
s[n] = p;
n = n+1;
bubbleUp(n - 1); // needs to subtract 1 because we do the addition
}
public void bubbleUp(int index) {
if (index == 0) {
return index;
}
else if (index > 0) {
int parentIndex = (index - 1) / 2; // Might not need to subtract 1
if (s[index].getKey() < s[parentIndex].getKey()) {
swapNode(index, parentIndex);
bubbleUp(parentIndex);
}
}
}
public void swapNode(int index, int parentIndex) {
Node temp = s[index];
s[index] = s[parentIndex];
s[parentIndex] = temp;
}
public void deleteMin(Node p) {
n = n - 1;
bubbleDown(s[0], s[n]);
return s[n];
}
public void bubbleDown(int index) {
if (index < 0) {
int leftChildIndex = (i*2) + 1;
int rightChildIndex = (i*2) + 2;
if (s[index].getKey() > s[leftChildIndex].getKey()) {
swapNode(index, leftChildIndex);
bubbleDown(leftChildIndex);
} else if (s[index].getKey() < s[leftChildIndex].getKey() && s[index].getKey() > s[rightChildIndex].getKey()) {
swapNode(index, rightChildIndex);
bubbleDown(rightChildIndex);
}
}
}
}
答案 0 :(得分:0)
首先,在bubbleUp()
中,您需要减去1才能找到父级。考虑0的子项为1和2.如果在除法之前没有减去1,那么2的父项将被错误地计算为1。
在findMin()
中,您应该在盲目返回根项目之前检查空堆。我知道你有一个isEmptySet()
函数,但如果你为空堆调用它,findMin()
应该抛出异常。
现在,在deleteMin()
和bubbleDown()
上。 deleteMin
应该是:
public void deleteMin(Node p){
n = n - 1;
// place root node at the end of the heap,
// and the last node at the root.
swapNode(0, n);
// adjust the heap
bubbleDown(0);
return s[n];
}
你拥有它的方式,deleteMin
是将节点而不是节点索引传递给bubbleDown
,当bubbleDown
只接受一个时,它传递了两个参数。
您的bubbleDown
走在正确的轨道上,但您必须小心。冒泡的规则是,如果节点大于其子节点,则将节点与两个子节点中的最小节点交换。并且你不能盲目地检查两个潜在的孩子,因为节点可能根本没有孩子。所以:
public void bubbleDown(int index){
int childIndex = (index * 2) + 1;
if (childIndex > n)
{
// if the first child index is off the end of the heap
// then the item has no children. (It's a leaf.)
return;
}
// first find the smallest child
// This test is to prevent checking a right child that doesn't exist.
if (childIndex < n)
{
if (s[childIndex] > s[childIndex+1])
{
childIndex = childIndex + 1;
}
}
// childIndex holds the index of the smallest of the node's children.
// swap if the parent is larger than the smallest child,
// and then keep bubbling down.
if (s[index] > s[childIndex])
{
swapNode(index, childIndex);
bubbleDown(childIndex);
}
}