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

标签 algorithm heapsort loop-invariant

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

最佳答案

循环不变量 是一种非常简单但功能强大的技术,可以证明您的算法或一组指令是否正确。他们在迭代中表现出色。

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

因此,您需要通过 3 个步骤证明您拥有所需的属性,即不变性:

我。 初始化:能否证明在循环迭代的第一步就具有算法的不变性?

二。 维护:你在维护不变性吗?如果到那一点为止的迭代为真,那么下一次迭代是否为真?

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

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

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

来源。 CLRS

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

根据我们上面的直觉,我们需要决定我们在整个算法中维护的所需属性。 MaxHeap 中所需的属性是什么?堆[i]>=堆[i*2]。无论您如何处理堆,如果它仍然具有该属性,那么它就是一个 MaxHeap。

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

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

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

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

因此你写的算法是正确的。

Introduction to Algorithms (CLRS) 对这种技术有很好的处理。

关于algorithm - 使用循环不变量证明堆排序的正确性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4364851/

相关文章:

java - 为什么优化的素因子计数算法运行速度较慢

c# - Dynamic Time Warping 算法对于嗡嗡声系统的查询有多合适?

python - 检查两个 Python 集合是否至少有一个共同元素

tree - 如何最好地描述 TreeSort 和 HeapSort 算法是什么?

c++ - 堆排序 CPU 时间

algorithm - QuickSort分区的循环不变量

java - 如何修复 'Codility FrogJump' 算法?

algorithm - 最小化中国余数定理中的余数

c - 堆排序中的数组索引

algorithm - 循环不变函数