我会试一试.这是一种通过一些解释来做你所要求的方法.
由于您知道堆中所有节点的一半是叶子,而叶子本身就是一个有效的堆,因此您只需要遍历另一半节点以确保它们也是有效的.如果我们从底层向上执行此操作,我们可以在堆栈中保持有效的堆结构“低于”.这可以通过for循环轻松完成:
public void rebuildHeap()
{
int half = heapArray.length / 2;
for(int i = half; i >= 0; i--)
restoreHeap(i);
}
那么如何实现restoreHeap?
它应该检查索引处的节点与其子节点,以查看它是否需要重定位节点.因为我们确保索引节点下面的树是堆,我们只需要将索引节点移动到正确的位置.因此我们将它在树中移动.
首先,我们需要找到孩子.由于三个节点中的每一行节点都是之前行的两倍,因此子节点的位置如下:
private void restoreHeap(int index)
{
int leftChild = (index * 2) + 1; //+1 because arrays start at 0
int rightChild = leftChild +1;
...
现在,您只需将子值与索引节点值进行比较即可.如果子级具有更大的值,则需要将索引节点与子节点交换.如果两个子节点都有较大的值,则需要与具有最大值的子节点交换(在交换后保持堆结构).交换节点后,您需要再次调用该方法,以查看是否需要将索引节点向下移动到树下.
...
int biggest = index;
if(leftChild < currentSize && heapArray[leftChild].getKey() > heapArray[index].getKey())
biggest = leftChild; //LeftChild is bigger
if(rightChild < currentSize && heapArray[rightChild].getKey() > heapArray[biggest].getKey())
biggest = rightChild; //RightChild is bigger than both leftChild and the index node
if(biggest != index) //If a swap is needed
{
//Swap
Node swapper = heapArray[biggest];
heapArray[biggest] = heapArray[index];
heapArray[index] = swapper;
restoreHeap(biggest);
}
}