简体   繁体   中英

Max Heap Insertion and Sorting Java

I am trying to construct a Max Heap and as each new value is inserted the value gets shifted up or down into its correct position, I have yet to implement a shift down function so as of right now I'm using a test that should only require the program to shift up. The test data is entered in the following order:

[16, 10, 14, 9, 7, 1, 4, 2, 8, 3]

I'm using the following code in the main class to insert the values in the heap:

package com.company;

public class Main {

    public static void main(String[] args) {

        BinaryHeap bh = new BinaryHeap();

        bh.insert(16);
        bh.insert(10);
        bh.insert(14);
        bh.insert(9);
        bh.insert(7);
        bh.insert(1);
        bh.insert(4);
        bh.insert(2);
        bh.insert(8);
        bh.insert(3);

        bh.printHeap();

    }
}

And this next bit of code is where the insertion and the shifting takes place:

package com.company;

public class BinaryHeap {
    private int[] Heap;
    private int size;
    private int maxsize;

    public BinaryHeap(){
        this.maxsize = 10;
        this.size = 0;
        Heap = new int[this.maxsize + 1];
    }

    public int Parent(int i){

        return (i)/2;
    }

    public int LeftChild(int i){

        return (2*i);
    }

    public int RightChild(int i){

        return ((2*1)+1);
    }

    public void insert(int value) {
        if(size <= Heap.length) {
            size++;
            Heap[size] = value;
            siftUp(size);
        }
    }


    private void siftUp(int i) {
        int parentIndex;
        int tmp;

        if (i != 0) {

            parentIndex = Parent(i);

            if (Heap[parentIndex] < Heap[i]) {
                tmp = Heap[parentIndex];
                Heap[parentIndex] = Heap[i];
                Heap[i] = tmp;
                siftUp(parentIndex);
            }

        }

    }

    public void printHeap()
    {
        for (int i = 1; i < maxsize; i++) {
            System.out.print(" PARENT : " + Heap[Parent(i)]
                    + " LEFT CHILD : " + Heap[LeftChild(i)]
                    + " RIGHT CHILD :" + Heap[RightChild(i)]);
            System.out.println();
        }
    }

}

The shifting function is siftUp() which I think is the issue. When the program is run with these outputs:

PARENT : 16 LEFT CHILD : 9 RIGHT CHILD :10
 PARENT : 14 LEFT CHILD : 8 RIGHT CHILD :10
 PARENT : 14 LEFT CHILD : 1 RIGHT CHILD :10
 PARENT : 9 LEFT CHILD : 0 RIGHT CHILD :10
 PARENT : 9 LEFT CHILD : 3 RIGHT CHILD :10
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 12 out of bounds for length 11
    at com.company.BinaryHeap.printHeap(BinaryHeap.java:61)
    at com.company.Main.main(Main.java:20)

But this isn't correct because 1) the index out of bounds exception at the end which is coming from the printHeap() function and 2)The Children of each parent node are not in the right place, because the root node should be 16 with 14 and 10 as children, also when it prints out the values for the heap, it prints off a 0 however 0 is never inserted into the heap. I've tried doing some of my own debugging but with not much success so any help with this is welcome.

private void siftUp(int i) {
    int parentIndex;
    int tmp;
    if (i != 0) { // error is this if statement
        parentIndex = Parent(i);
        if (Heap[parentIndex] < Heap[i]) {
            tmp = Heap[parentIndex];
            Heap[parentIndex] = Heap[i];
            Heap[i] = tmp;
            siftUp(parentIndex);
        }
    }
}

The error that is causing your Heap to not displaying the correct number is here inside siftUp, the if statement.

When you insert 16, Heap[1] becomes 16. Then, it calls siftUp(1) . Inside siftUp, 1 != 0, so the if statements are executed. parentIndex becomes 1/2 = 0, and here comes the problem. Heap[0] = 0 by default is less than Heap[1] = 16. Thus, it swaps the value 16 and 0, moving 16 to index 0 which is not the head as you mentioned. This is just the beginning of the errors, and as you insert more and more numbers, they become all over the place.

Since your root of the Heap is at index 1. You should only sift until index 1, which has no Parent. After changing the if statement to if(i > 1) , and modifying your printHeap(), I get this output, which I think is correct. You should also print the current value at the current index in the heap.

 PARENT: 0 CURRENT: 16 LEFT CHILD : 10 RIGHT CHILD : 14 
 PARENT: 16 CURRENT: 10 LEFT CHILD : 9 RIGHT CHILD : 7
 PARENT: 16 CURRENT: 14 LEFT CHILD : 1 RIGHT CHILD : 4
 PARENT: 10 CURRENT: 9 LEFT CHILD : 2 RIGHT CHILD : 8
 PARENT: 10 CURRENT: 7 LEFT CHILD : 3
 PARENT: 14 CURRENT: 1
 PARENT: 14 CURRENT: 4
 PARENT: 9 CURRENT: 2
 PARENT: 9 CURRENT: 8
public void printHeap(){
  for (int i = 1; i < maxsize; i++) {
    System.out.print(" PARENT: " + Heap[Parent(i)]);
    System.out.print(" CURRENT: "+ Heap[i]);
    if(LeftChild(i) <=  10){
      System.out.print(" LEFT CHILD " + ": " +  Heap[LeftChild(i)]);
    } 
    if(RightChild(i) <= 10){
      System.out.print(" RIGHT CHILD "+ ": "+  Heap[RightChild(i)]);
      }
    System.out.println();
  }
}

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