Max Heap没有按预期工作

时间:2016-05-25 19:52:14

标签: java algorithm data-structures heap binary-heap

我对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);
            }
        }


    }

2 个答案:

答案 0 :(得分:1)

罪魁祸首就是这条线:

heap[++size] = n;

当您插入第一个元素时,您将插入位置1,并且按照您执行的步骤,堆[0]&amp;每次插入后,heap [1]将最终具有相同的值。这就是为什么你会在每次插入后看到父和左孩子具有相同的值。

例如,当您插入第一个元素时,您尝试在heap [1]处插入,并在heap [0]和amp;之间执行交换。堆[1]。结果是你在堆[0]和...中得到相同的值。堆[1]。

答案 1 :(得分:1)

insertremove方法中,代码假定根节点位于heap[1]。但是您的print方法认为堆中的根节点位于heap[0]。这将导致你遇到各种各样的麻烦。

另请注意,remove方法不会减少size