为了使堆的实现更加健壮,人们通常将您可以对节点进行的两个操作称为:sift
和percolate
sift
通过用你找到的两个儿子中最好的一个来切换节点,尽可能地将节点放在树上。
有可能执行该sift
程序
public void sift (int i)
{
while (i != 0)
{
if (compare(heapData[i], parentValue(i)))
{
switchValuesAtIndexes(parentIndex(i), i);
i = parentIndex(i);
}
else
break;
}
}
percolate
通过与父节点切换节点,将节点尽可能地放在树上。
public void percolate (int i)
{
while (true)
{
if (indexExists(leftIndex(i)) && (!indexExists(rightIndex(i)) && compare(leftValue(i), heapData[i]) || indexExists(rightIndex(i)) && compare(leftValue(i), rightValue(i)) && compare (leftValue (i), heapData[i])))
{
switchValuesAtIndexes(leftIndex(i), i);
i = leftIndex(i);
}
else
if (indexExists(rightIndex(i)) && (compare (rightValue(i), leftValue(i)) && compare (rightValue(i), heapData[i])))
{
switchValuesAtIndexes(rightIndex(i), i);
i = rightIndex(i);
}
else
break;
}
}
要构建堆,您需要对数组的每个元素应用sift
或(或两者)percolate
要对您构建的堆进行排序,您必须打印第一个元素(这是与您定义的比较器、最小值、最大值等相关的所有堆中最好的)然后您必须用最后一个“覆盖”第一个元素并删除最后一个,然后您必须应用sift
第一个元素以将其带到堆中的正确位置。然后重复直到堆中没有元素