java - while循环只在deleteMax()堆方法中执行一次

标签 java while-loop heap

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();

    }
}

我的问题是:为什么我的 while 循环只执行一次?我希望我的 deleteMax 方法删除最大节点(根节点),然后对堆进行正确排序,使其再次成为最大堆。最大堆如下: 20 18 15 8 11 10 7 2 6 5 4 3 1

一旦 deleteMax 被调用,它应该输出: 18 11 15 8 5 10 7 2 6 1 3 4

但它却输出: 18 1 15 8 11 10 7 2 6 5 4 3 1

很明显,它正在删除最大节点,将其替换为最底部的叶子,并将新根与其最大的子节点交换。然后它应该继续在堆中交换 1,但它在这样做之前停止了。

我为 while 循环尝试了很多不同的逻辑,包括:

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

并增加 i 但似乎没有任何效果。

最佳答案

您没有旋转根。您的循环体应如下所示。

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

你的 adjustHeap方法可能已经在执行此交换,我无法确定。最重要的是你需要在堆中旋转你的根(而不是比较分支),你不应该有 i++里面的声明。也应该是<而不是 <=>而不是 >= ,但这只是一个小的优化。

关于java - while循环只在deleteMax()堆方法中执行一次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15994105/

相关文章:

java - 使用 Java 查找和替换文本文件中的单词

java - 如何将此 FOR 循环转换为 WHILE 循环,以便它也计算辅音? (Java)

algorithm - treap数据结构中的优先级生成

c# - 自定义堆二叉树实现——随机节点删除

java - 使用 Mockito 进行单元测试 - 忽略方法调用

java - 单例模式: getInstance() vs Passing the singleton object?

java - 使用 runtime.getRuntime().exec() 时 Jar 文件如何工作

python - Pandas 使用 while 循环遍历数据框和列表

C在while循环中读取输入

go - 如何在 Go 中嵌入和覆盖结构