我对Max Heap的Java代码没有按预期工作。当我从堆中删除时,它不会返回90作为最大值。
/**
* Created by mona on 5/25/16.
*/
public class Heap {
private int[] heap;
private int size;
private int maxSize;
public Heap(int maxSize) {
this.maxSize=maxSize;
this.size=0;
heap=new int[this.maxSize+1];
}
private int parent(int pos) {
return pos/2;
}
private int leftChild(int pos) {
return pos*2;
}
private int rightChild(int pos) {
return pos*2 +1;
}
private boolean isLeaf(int pos) {
if (pos>=size/2 && pos<=size) {
return true;
}
return false;
}
private void swap(int pos1, int pos2) {
int tmp=heap[pos1];
heap[pos1]=heap[pos2];
heap[pos2]=tmp;
}
private void maxHeapify(int pos) {
if (!isLeaf(pos)){
if ((heap[pos] < heap[leftChild(pos)]) ||
(heap[pos] < heap[rightChild(pos)])) {
if (heap[leftChild(pos)] > heap[rightChild(pos)]) {
swap(pos , leftChild(pos));
maxHeapify(leftChild(pos));
}
else {
swap(pos , rightChild(pos));
maxHeapify(rightChild(pos));
}
}
}
}
public void maxHeap() {
for (int i=(size/2) ; i>=1 ; i--) {
maxHeapify(i);
}
}
public void insert(int n) {
heap[++size] = n;
int tmpLocation = size;
while (heap[tmpLocation] > heap[parent(tmpLocation)]){
swap(tmpLocation , parent(tmpLocation));
tmpLocation=parent(tmpLocation);
}
}
public int remove() {
int removed = heap[1];
heap[1] = heap[size-1];
maxHeapify(1);
return removed;
}
public void print() {
for (int i=1 ; i<=(size/2) ; i++) {
System.out.println("current node is: "+heap[i]+" its left child is " +
heap[i*2]+" its right child is "+heap[i*2 +1]);
}
}
public static void main(String[] args) {
Heap heap = new Heap(9);
heap.insert(8);
heap.insert(18);
heap.insert(28);
heap.insert(9);
heap.insert(12);
heap.insert(90);
heap.insert(1);
heap.insert(87);
heap.maxHeap();
heap.print();
System.out.println("Max is: "+heap.remove());
}
}
这是输出:
current node is: 90 its left child is 90 its right child is 87
current node is: 87 its left child is 28 its right child is 18
current node is: 28 its left child is 12 its right child is 9
current node is: 18 its left child is 8 its right child is 1
current node is: 12 its left child is 0 its right child is 0
Max is: 87
Process finished with exit code 0
另外你可以在输出的第一行看到它表示90岁的孩子是90,这是不对的。那是什么?
current node is: 90 its left child is90 its right child is 87
更新:当我将大小设置为8时,我收到此错误:
Exception in thread "main" current node is: 90 its left child is90 its right child is 87
current node is: 87 its left child is28 its right child is 18
current node is: 28 its left child is12 its right child is 9
current node is: 18 its left child is8 its right child is 1
java.lang.ArrayIndexOutOfBoundsException: 9
at Heap.print(Heap.java:86)
at Heap.main(Heap.java:104)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
Process finished with exit code 1
更新:我想如果我将插入更改为以下内容会有所帮助,但不会:
public void insert(int n) {
size++;
heap[size] = n;
int tmpLocation = size;
if (tmpLocation!=1) {
while (heap[tmpLocation] > heap[parent(tmpLocation)]) {
swap(tmpLocation, parent(tmpLocation));
tmpLocation = parent(tmpLocation);
}
}
}
答案 0 :(得分:1)
罪魁祸首就是这条线:
heap[++size] = n;
当您插入第一个元素时,您将插入位置1,并且按照您执行的步骤,堆[0]&amp;每次插入后,heap [1]将最终具有相同的值。这就是为什么你会在每次插入后看到父和左孩子具有相同的值。
例如,当您插入第一个元素时,您尝试在heap [1]处插入,并在heap [0]和amp;之间执行交换。堆[1]。结果是你在堆[0]和...中得到相同的值。堆[1]。
答案 1 :(得分:1)
在insert
和remove
方法中,代码假定根节点位于heap[1]
。但是您的print
方法认为堆中的根节点位于heap[0]
。这将导致你遇到各种各样的麻烦。
另请注意,remove
方法不会减少size
。