简体   繁体   English

如何堆化最大堆?

[英]How to heapify Max-heap?

I'm trying to implement a Max-heap with with two methods insert and extract_max .我正在尝试使用两种方法insertextract_max来实现最大堆。 But the extract_max is currently not working correctly as it's not extracting the largest integer in the Heap, which i assume is because of heapify .但是extract_max目前无法正常工作,因为它没有提取堆中最大的 integer ,我认为这是因为heapify I've been trying to debug for hours but can't figure out where it goes wrong.我一直在尝试调试几个小时,但无法弄清楚哪里出了问题。 Any input would be highly appreciated.任何输入将不胜感激。

class Heap {
    int heap_array[];
    int n_elems = 0;
    int capacity;

    // Constructor
    Heap(int _capacity) {
        capacity = _capacity;
        heap_array = new int[capacity];
    }


    /**
     * Private method for maintaining the heap.
     * @param i, index of the element to heapify from
     **/
    private void heapify(int i) {
        int left = 2*i + 1;
        int right = 2*i+ 2;
        int largest = i;
        //if left ≤ heap_length[A] and A[left] > A[largest] then:
        if (left <= n_elems && heap_array[left] > heap_array[largest]) {
            largest = left;
            //System.out.println("largest = left");
        }

        //if right ≤ heap_length[A] and A[right] > A[largest] then:
        if (right <= n_elems && heap_array[right] > heap_array[largest]) {
            //System.out.println("largest = right");
            largest = right; 
        }
        //if largest ≠ i then:
        if (largest != i) { 
            int swap = heap_array[i]; 
            heap_array[i] = heap_array[largest]; 
            heap_array[largest] = swap; 

            // Recursively heapify the affected sub-tree 
            heapify(largest); 
        } 
    }

    /**
     * Add an element to the heap and ensure the heap property
     * Throws an exception if trying to add elements to a full heap.
     * @param x Element to add
     */
    public void insert(int x) throws Exception {
        if(is_full()) {
            throw new Exception("The heap is full");
        } else {
            // Insert the element at end of Heap 
            heap_array[n_elems++] = x; 
            //n_elems++;
            // Heapify from root
            heapify(0); 


        }

    }


   public int extract_max() throws Exception {
    //Get the largest
       // Get the last element 
    int root = heap_array[0];

       int lastElement = heap_array[n_elems]; 

       // Replace root with first element 
       heap_array[0] = lastElement; 

       // Decrease size of heap by 1 
       n_elems--;

       // heapify the root node 
       heapify(0);

       // return new size of Heap 
       return root;

   }

    public int capacity() {
        return capacity;
    }

    public int size() {
        return n_elems;
    }

    public boolean is_empty() {
        return n_elems == 0;
    }

    public boolean is_full() {
        return n_elems == capacity;
    }

    public void print() {
        for(int i = 0; i < n_elems; i++) {
            System.out.println(heap_array[i]);
        }
    }





    /**
     * Remove and return largest element, and maintain the heap property.
     * Throws an exception if trying to extract an element from an empty heap.
     */



    /**
     * For convenience, a small program to test the code.
     * There are better ways of doing this kind of testing!
     * @throws Exception 
     *
     */
    static public void main(String args[]) throws Exception { // A simple test program
        // Declare two heaps. Both should work nicely!
        Heap h1 = new Heap(100);
        Heap h2 = new Heap(10);
        int data[] = {1, 4, 10, 14, 7, 9, 3, 8, 16};


        //
        // Insert 1 element to heap 1, and several to heap 2.
        //

        h2.insert(9);
        h2.insert(10);
        h2.insert(8);
        h2.insert(11);
        h2.insert(12);
        h2.insert(15);
        System.out.println("Size " + h2.size());
        h2.print();

        System.out.println("Max " + h2.extract_max());
    }  
}

The first problem is that your insert isn't correct.第一个问题是您的insert不正确。 Just adding to the end and calling heapify(0) doesn't do you any good.只是添加到最后并调用heapify(0)对你没有任何好处。 heapify is going to examine the root element and its two children, decide that the root is the largest item, and exit, doing nothing. heapify将检查根元素及其两个子元素,确定根是最大的元素,然后退出,什么也不做。 As a result, you're just adding things to the list sequentially.结果,您只是按顺序将内容添加到列表中。

To insert into a max-heap, you do the following:要插入最大堆,请执行以下操作:

  1. Add the new item to the end of the heap.将新项目添加到堆的末尾。
  2. Move the item up the heap to its proper position.将项目向上移动到正确的 position。

So insert should look like this:所以insert应该是这样的:

public void insert(int x) throws Exception {
    if(is_full()) {
        throw new Exception("The heap is full");
    }
    // Insert the element at end of Heap 
    heap_array[n_elems++] = x; 

    // now sift it up
    int current = nelems-1;
    int parent = (current-1)/2;
    while (current > 0 && heap_array[current] > heap_array[parent]) {
        int swap = heap_array[parent];
        heap_array[parent] = heap_array[current];
        heap_array[current] = swap;
        current = parent;
        parent = (current-1)/2;
    }
}

I think you also have a problem in extract_max .我认为您在extract_max也有问题。 You have:你有:

int lastElement = heap_array[n_elems];

But the last element is actually at index n_elems-1] .但最后一个元素实际上位于索引n_elems-1]处。 I think you want:我想你想要:

int lastElement = heap_array[n_elems-1];

That makes sense because if n_elems == 1 , then the only item in the heap will be the root, at heap_array[0] ;这是有道理的,因为如果n_elems == 1 ,那么堆中唯一的项目将是根,在heap_array[0]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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