gpt4 book ai didi

java - Java 最大堆插入和排序

转载 作者:行者123 更新时间:2023-12-02 08:55:42 24 4
gpt4 key购买 nike

我正在尝试构建一个最大堆,并且当插入每个新值时,该值会向上或向下移动到正确的位置,我还没有实现下移功能,所以现在我正在使用测试这只需要程序向上移动。测试数据按以下顺序输入:

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

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

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

}
}

下一段代码是插入和移位发生的地方:

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

}

移位函数是 siftUp() 我认为这是问题所在。当程序以这些输出运行时:

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)

但是这是不正确的,因为 1) 来自 printHeap() 函数的末尾索引越界异常以及 2) 每个父节点的子节点不在正确的位置,因为根节点应该是 16,其中 14 和 10 作为子级,而且当它打印出堆的值时,它会打印出 0,但是 0 永远不会插入到堆中。我尝试过自己进行一些调试,但没有取得太大成功,因此欢迎任何帮助。

最佳答案

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

关于java - Java 最大堆插入和排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60496782/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com