簡體   English   中英

用Java調試Max Heap

[英]Debugging Max Heap in Java

不久以前,我正在用C ++編程,並且找到了有關制作最大堆的教程。 這是代碼,似乎產生了正確的順序堆。

#include <iostream>

const int size = 14;
static int A[size] = {1, 2, 5, 10, 2, 11, 12, 7, 23, 22, 34, 54, 12, 22};

int left(int i)
{
    return (2*i)+1;
}

int right(int i)
{
    return (2*i)+2;
}

//a leaf of a value less than the size of the array
//and larger than the center of the array
bool isLeaf(int i)
{
    if(i >= (size/2) && i <= size)
    {
        return true;
    }
    return false;
}

void maxHeapify(int i)
{
    //if it isn't a leaf it may need to be swapped
    if(!isLeaf(i))
    {
        //if the value is less than it's right or left child
        if(A[i] < A[left(i)] || A[i] < A[right(i)])
        {
            //if the left child is smaller
            if(A[left(i)] > A[right(i)])
            {
                //swap the left child with the index
                std::cout << "Swapping " << A[i] << " and " << A[left(i)] << std::endl;
                int a = A[i];
                A[i] = A[left(i)];
                A[left(i)] = a;
                //and run maxHeapify in it. This will push the value to
                //it's lowest point and order all things below the parent
                maxHeapify(left(i));
            }
            else
            {
                //else swap with the right child since it is larger
                std::cout << "Swapping " << A[i] << " and " << A[right(i)] << std::endl;
                int a = A[i];
                A[i] = A[right(i)];
                A[right(i)] = a;
                //run maxheap on that value. This will push the value to it's lowest position
                maxHeapify(right(i));
            }
        }
    }
}


bool buildHeap()
{
    //need to run for each node that is not a leaf
    for(int i = (size/2); i >= 0; i--)
    {
        maxHeapify(i);
    }
    return true;
}


int main()
{
    std::cout << "before: " << std::endl;
    for(int i = 0; i < size; i++)
    {
        std::cout << A[i] << ", ";
    }
    std::cout << std::endl;
    buildHeap();
    std::cout << "After: " << std::endl;
    for(int i = 0; i < size; i++)
    {
        std::cout << A[i] << ",";
    }
    std::cout << std::endl;
    return 0;
}

上面的輸出是:
之前:
1,2,5,10,2,11,12,7,23,22,34,54,12,22,
交換12和22
交換11和54
交換2和34
交換10和23
交換5和54
交換5和12
交換2和34
交換2和22
交換1和54
交換1和22
交換1和12

后:
54,34,22,23,22,12,12,7,10,2,2,11,5,1,

目前,我正在學習一個期中考試,並且試圖在Java中重現我的代碼。 我已經看了一段時間了,但似乎找不到我要去哪里。 這是壞掉的Java:Main.java

public class Main {

    /**
     * @param args
     */
    public static void main(String[] args) {
        int[] a = { 1, 2, 5, 10, 2, 11, 12, 7, 23, 22, 34, 54, 12, 22 };
        System.out.println("Begfore");
        for (int i = 0; i < a.length; i++) {
            System.out.print(a[i] + ", ");
        }
        Heap h = new Heap(a);
        h.buildHeap();
        h.print();
        System.out.println();
        System.out.println(a.length);
    }
}

Heap.java

public class Heap {

    int[] heap;

    public Heap(int[] a) {
        // heap = new int[a.length];
        heap = a;
    }

    public void buildHeap() {
        for (int i = heap.length / 2; i >= 0; i--) {
            maxHeapify(i);
        }
    }

    public int getLeft(int a) {
        return (2 * a) + 1;
    }

    public int getRight(int a) {
        return (2 * a) + 2;
    }

    private boolean isLeaf(int a) {
        if (a >= ((heap.length) / 2) && a <= heap.length) {
            return true;
        } else {
            return false;
        }
    }

    public void maxHeapify(int a) {
        if (!isLeaf(a)) {
            if (heap[a] < heap[getLeft(a)] || heap[a] < heap[getRight(a)]) {
                if (getLeft(a) <= heap.length && getRight(a) < heap.length) {
                    if (heap[getLeft(a)] > heap[getRight(a)]) {
                        int watcher = heap[a];
                        heap[a] = heap[getLeft(a)];
                        heap[getLeft(a)] = watcher;
                        maxHeapify(getLeft(a));
                    } else {
                        int watcher = heap[a];
                        heap[a] = heap[getRight(a)];
                        heap[getRight(a)] = watcher;
                        maxHeapify(getRight(a));
                    }
                }
            }
        }
    }

    public void print() {
        System.out.println("heap");
        for (int i = 0; i < heap.length; i++) {
            System.out.print(heap[i] + ", ");
        }
    }
}

這不會產生正確的最大有序堆。
Java輸出:54、34、12、23、22、12、1、7、10、2、2、11、5、22,

此代碼有一些基本問題。 讓我解釋一下。

首先,在Max Heapify函數中,您無需檢查是否為葉子的條件。 這將我帶到您的最大heapify函數調用。

始終從索引heap.length / 2-1到0調用heapify函數,請注意您尚未使用-1。 這樣可以始終從葉子中保存heapify,因為在二進制堆中,無論max on min,葉子都位於從heap.length / 2到heap.length-1的索引處。

此代碼的另一個錯誤是使用索引的方式。 有兩種使用索引的方法。

在這種情況下,都不應使用從0到heap.length -1的實數索引

<=heap.length or >=heap.length

但是您在堆代碼中使用了這樣的條件。

或者使用偽索引,范圍從1到heap.length,在[]中使用它們時,只需減去-1。 這在我的Java代碼中完美運行。

希望這可以幫助。 如果需要,我可以給您Java代碼。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM