最大堆插入和Java排序

时间:2020-03-02 21:16:00

标签: java sorting max-heap

我正在尝试构造一个Max Heap,并且在插入每个新值时,该值会向上或向下移动到正确的位置,但我尚未实现向下移动功能,因此到目前为止,我正在使用测试那只需要程序上移。按以下顺序输入测试数据:

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

我在主类中使用以下代码在堆中插入值:

extractfile

接下来的代码是插入和移动的地方:

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

    }
}

移位功能是siftUp(),我认为这是问题所在。使用以下输出运行程序时:

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

}

但是这是不正确的,因为1)最后是来自printHeap()函数的索引超出范围异常,以及2)每个父节点的子代都不在正确的位置,因为根节点应该是16,其中14和10是子级,同样,当它打印出堆的值时,它会打印出0,但是永远不会将0插入到堆中。我尝试做一些自己的调试,但没有成功,因此欢迎您提供任何帮助。

1 个答案:

答案 0 :(得分:1)

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

导致堆无法显示正确数字的错误在siftUp的if语句中。

当您插入16时,Heap[1]变为16。然后,它调用siftUp(1)。在siftUp内部,1!= 0,因此将执行if语句。 parentIndex变为1/2 = 0,这就是问题所在。默认情况下,Heap [0] = 0小于Heap [1] =16。因此,它将值16和0交换,将16移到索引0(不是您提到的头)。这只是错误的开始,随着您插入越来越多的数字,这些错误无处不在。

由于您的堆的根位于索引1,因此只能筛选直到索引1(没有父级)。 将if语句更改为if(i > 1),并修改了printHeap()之后,我得到了此输出,我认为这是正确的。您还应该在堆中的当前索引处打印当前值。

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