使用循环不变量来证明堆排序的正确性

时间:2010-12-06 09:22:22

标签: algorithm heapsort loop-invariant

什么是循环不变量?如何使用它们来证明堆排序算法的正确性?

3 个答案:

答案 0 :(得分:8)

循环不变量是非常简单但功能强大的技术,用于证明您的算法或一组指令是否正确。它们在迭代中运行得非常好。

我们设置了一个不变属性,这是您希望在整个执行过程中保持的迭代中的所需属性。例如,如果你开始使用正确的状态并在整个算法过程中保持它,那么你知道你有一个正确的算法

所以你需要通过3个步骤显示你有一个所需的属性,不变性:

我。 初始化:您是否可以在循环迭代的第一步中显示您具有算法的不变属性?

II。 维护:您是否保持不变性?如果到那一点的迭代都是如此,下一次迭代是否属实?

iii。终止:当您的循环终止时,将使用不变量来表明您编写的算法是正确的。

让我们使用这些知识来证明BuildMaxHeap是正确的,因为它在HeapSort算法中使用。

BuildMaxHeap(A)
  heap-size[A] = length[A]
   for i : length[A]/2 to 1
       Max-Heapify(A, i)

源。 CLRS

例如,我们怎么知道最大堆的构建实际上构建了一个最大堆!如果我们的BuildMaxHeap算法正常工作,我们可以使用它来正确排序。

遵循我们的上述直觉,我们需要决定我们在整个算法中维护的所需属性。 MaxHeap中所需的属性是什么? heap [i]> = heap [i * 2]。无论你有多乱用堆,如果它仍然具有该属性,那么它就是MaxHeap。

因此,我们需要确保用于排序的BuildMaxHeap算法在整个算法中保持不变。

初始化:在第一次迭代之前。一切都是叶子所以它已经是一堆了。

维护:让我们假设到目前为止我们有一个有效的解决方案。节点i的子节点编号高于i。 MaxHeapify也保留了循环不变量。我们在每一步都保持不变性。

终止:当i下降到0并且循环不变时终止,每个节点都是最大堆的根。

因此您编写的算法是正确的。

算法简介(CLRS)对此技术有很好的处理。

答案 1 :(得分:1)

循环不变量是一个在循环执行期间不会改变的“定律” 在堆排序中 - 不变量是每个节点都有堆属性 - 也就是说,节点中的值大于其左右子节点的值。

答案 2 :(得分:0)

BuildMaxHeap的正确性

•循环不变:在for循环的每次迭代开始时,每个节点i + 1,i + 2,...,n是最大堆的根。

•初始化: - 在第一次迭代之前i =⎣n/2⎦               -Nodes⎣n/2⎦+ 1,⎣n/2⎦+ 2,...,n是叶子,因此是平凡最大堆的根。

•维护: - 通过LI,节点i的子节点的子树是最大堆。 -Hence,MaxHeapify(i)将节点i渲染为最大堆根(同时保留更高编号节点的最大堆根属性)。               -crementing i重新建立下一次迭代的循环不变量。