具有一个insert函数,该函数应将元素插入堆中。
form.js
带有print语句的for循环用于示例输出,我将继续介绍。 parent(i)获得i / 2,大小为当前堆大小。
这是交换功能:
public void insert(int element) {
Heap[++this.size] = element;
int i = this.size;
while (Heap[i] > Heap[parent(i)]) {
swap(i, parent(i));
i = parent(i);
}
for (int j = 0; j < size; j++)
System.out.println(Heap[j]);
System.out.println();
}
我输入的样本元素是950、800、850、900、850、1000。Insert()中的for循环用于显示我放置的值(每次插入之间都有新行)。 / p>
我不明白为什么将800的值设置为0。然后将其恢复为800,但是此后将其设置为0。我的代码的哪一部分为其提供了此功能?
答案 0 :(得分:1)
您的insert
方法中的问题就在这里:
Heap[++this.size] = element;
int i = this.size;
因此,第一次调用insert
时,您的数组如下所示:
Heap[0] = 0
Heap[1] = 950
this.size
为1,然后从索引1开始对堆进行筛选。
这只会很糟糕地结束。在第二次插入之后,您的数组包含[950,800]
,并且this.size
等于2。现在,让我们看看在插入850时第三次插入会发生什么。
Heap[++this.size] = 850
因此this.size
递增,使其变为3。在Heap[3]
处插入值850,得到[900, 800, 0, 850]
。对应于此堆:
900
/ \
800 0
/
850
您的代码正确地重新排列了堆,从而为您提供:
900
/ \
850 0
/
800
对应于数组[900, 850, 0, 800]
。
问题是您在插入元素之前 增大了大小。您需要在插入后 递增。然后,由于它是从0开始的,因此您希望起始索引为size-1
。
这是更正的方法。
public void insert(int element) {
Heap[this.size++] = element;
int i = this.size-1;
while (i > 0 && Heap[i] > Heap[parent(i)]) {
swap(i, parent(i));
i = parent(i);
}
for (int j = 0; j < size; j++)
System.out.println(Heap[j]);
System.out.println();
}
顺便说一句,在基于0的堆中,节点i的父节点应该是(i-1)/2
。