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

Algorithm 用循环不变量证明堆排序的正确性,algorithm,heapsort,loop-invariant,Algorithm,Heapsort,Loop Invariant,什么是循环不变量?如何使用它们来证明堆排序算法的正确性?循环不变量是一个在循环执行过程中不会改变的“定律”。 在堆排序中,不变量是每个节点都有heap属性,也就是说,节点中的值大于其左、右子节点的值。循环不变量是非常简单但功能强大的技术,用于证明算法或一组指令是否正确。它们在迭代中工作得非常出色 我们设置了一个不变属性,这是迭代中所需的属性,您希望在整个执行过程中保持该属性。例如,如果你从一个正确的状态开始,并在整个算法过程中保持它,那么你知道你有一个正确的算法 因此,您需要通过三个步骤证明您具

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

循环不变量是一个在循环执行过程中不会改变的“定律”。

在堆排序中,不变量是每个节点都有heap属性,也就是说,节点中的值大于其左、右子节点的值。

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

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

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

一,初始化:在循环迭代的第一步中,您能证明您具有算法的不变特性吗

二,维护:您是否保持不变性?如果到那时为止,迭代是正确的,那么下一次迭代是正确的吗

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

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

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

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

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

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

BuildMaxHeap(A)
  heap-size[A] = length[A]
   for i : length[A]/2 to 1
       Max-Heapify(A, i)
初始化:在第一次迭代之前。一切都是一片叶子,所以它已经是一堆了

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

终止:当i下降到0时终止,通过循环不变量,每个节点都是max堆的根

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

《算法简介》(CLR)很好地介绍了这项技术。

BuildMaxHeap的正确性

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

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

•维护:–根据LI的说法,节点i的子节点上的子树是最大堆。 –因此,MaxHeapify(i)将节点i渲染为最大堆根(同时保留编号较高节点的最大堆根属性)。
–递减i将为下一次迭代重新建立循环不变量

这闻起来很像一项任务。你想出了什么,哪里有困难?lol不,我只是为了测试而学习。可能的重复我不认为这应该作为重复关闭,因为我认为允许用户找到一篇关于使用循环不变量来证明堆排序正确性的文章是有用的(特别是)。对于初始化,“一切都是一片叶子”如何? 我读得太慢了,因为houri=floor(n/2)是最后一个内部节点(非叶节点),否则left=2i和right=2i+1将超过n。因此,楼层(n/2)+1,…,n都是外部节点(叶节点)。例如,如果n=11,则楼层(11/2)+1=6。6不能生孩子,因为左=6*2=12,右6*2+1=13没有意义,因为n=11。