简体   繁体   中英

while loop only executes once in deleteMax() heap method

package x;

public class MaxHeap {

    private Element[] heapArray;
    private int maxSize;
    private int currentSize;

    public MaxHeap(int max) {
        maxSize = max;
        currentSize = 0;
        heapArray = new Element[maxSize]; // create the heap
    }

    public boolean isEmpty() {
        return currentSize == 0;
    }

    // Move an element up in the heap tree.
    public void adjustHeap(int index) {

        int parent = (index - 1) / 2;
        Element bottom = heapArray[index];

        while (index > 0 && heapArray[parent].getData() < bottom.getData()) {
            heapArray[index] = heapArray[parent]; // move it down
            index = parent;
            parent = (parent - 1) / 2;
        }
        heapArray[index] = bottom;
    }

    public boolean insert(int key) {
        if (currentSize == maxSize)
            return false;
        Element newElement = new Element(key);
        heapArray[currentSize] = newElement;
        adjustHeap(currentSize++);
        return true;
    }

    public Element[] getMaxHeap() {

        return heapArray;
    }

    public void printHeap() {
        int i;
        for (i = 0; i < maxSize; i++)
            System.out.print(heapArray[i].getData() + " ");
        System.out.println();
    }

    public void deleteMax() {
        heapArray[0].setData(heapArray[maxSize - 1].getData());
        currentSize--;

        int i = 0;
        while (i<=heapArray[maxSize - 1].getData()) {

            int left = 2 * i + 1;
            int right = 2 * i + 2;      

            if (heapArray[left].getData() <= heapArray[right].getData()) {
                i = (2 * i + 1);
                adjustHeap(right);
                i++;
            }
            if (heapArray[left].getData() >= heapArray[right].getData()) {
                i = (2 * i + 2);
                adjustHeap(left);
                i++;
            }

        }
    }
}

    package x;

    class Element {
        private int inData;
        public Element(int data){
            inData = data;
        }
        public int getData(){
            return inData;
        }
        public void setData(int data){
            inData = data;
        }
    }

package x;

public class Test {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub

        MaxHeap heap = new MaxHeap(13);
        heap.insert(2);
        heap.insert(20);
        heap.insert(10);
        heap.insert(5);
        heap.insert(6);
        heap.insert(15);
        heap.insert(7);
        heap.insert(8);
        heap.insert(18);
        heap.insert(11);
        heap.insert(4);
        heap.insert(3);
        heap.insert(1);

        heap.printHeap();
        System.out.println("\n");


        heap.deleteMax();
        heap.printHeap();

    }
}

My question is: Why is my while loop only executing one time? I want my deleteMax method to delete the max node (the root) then properly sort the heap so that it again is a max heap. the max heap is the following: 20 18 15 8 11 10 7 2 6 5 4 3 1

once deleteMax is called it should output: 18 11 15 8 5 10 7 2 6 1 3 4

but it instead outputs: 18 1 15 8 11 10 7 2 6 5 4 3 1

clearly it is deleting the max node, replacing it with the bottom most leaf, and swapping the new root with its largest child. It should then go on to swap 1 down the heap, but it stops before doing so.

I have tried lots of different logic for the while loop including:

while(Math.floor(i/2) <= 2*i+1 && Math.floor(i/2) <= 2*i+2)

and increasing i but nothing seems to work.

You're not rotating the root. Your loop body should look something like this.

if (heapArray[left].getData() < heapArray[i].getData()) {
    temp = heapArray[i].getData();
    heapArray[i].setData(heapArray[left].getData());
    heapArray[left].setData(temp);
    i = (2 * i + 1);
 }
 else if (heapArray[right].getData() > heapArray[i].getData()) {
     temp = heapArray[i].getData();
     heapArray[i].setData(heapArray[right].getData());
     heapArray[right].setData(temp);
     i = (2 * i + 2);
 }

Your adjustHeap method might already be performing this swap, I couldn't be sure. The bottom line is that you need to rotate your root through the heap (rather than comparing branches), and you shouldn't have the i++ statement in there. It should also be < instead of <= and > instead of >= , but that's just a minor optimization.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM