了解快速排序算法如何在 VBA 中重现

Posted

技术标签:

【中文标题】了解快速排序算法如何在 VBA 中重现【英文标题】:Understanding how a quicksort algorithm recurs in VBA 【发布时间】:2019-05-21 03:59:03 【问题描述】:

我最近阅读了这篇文章:VBA array sort function?,看看我是否可以获得一些代码来在 Excel VBA 中实现快速排序算法。

我从帖子中获取以下代码并在 Excel 中实现:

   Public Sub QuickSort(vArray As Variant, inLow As Long, inHi As Long)
  Dim pivot   As Variant
  Dim tmpSwap As Variant
  Dim tmpLow  As Long
  Dim tmpHi   As Long

  tmpLow = inLow
  tmpHi = inHi

  pivot = vArray((inLow + inHi) \ 2)

  While (tmpLow <= tmpHi)
     While (vArray(tmpLow) < pivot And tmpLow < inHi)
        tmpLow = tmpLow + 1
     Wend

     While (pivot < vArray(tmpHi) And tmpHi > inLow)
        tmpHi = tmpHi - 1
     Wend

     If (tmpLow <= tmpHi) Then
        tmpSwap = vArray(tmpLow)
        vArray(tmpLow) = vArray(tmpHi)
        vArray(tmpHi) = tmpSwap
        tmpLow = tmpLow + 1
        tmpHi = tmpHi - 1
     End If
  Wend

  If (inLow < tmpHi) Then QuickSort vArray, inLow, tmpHi
  If (tmpLow < inHi) Then QuickSort vArray, tmpLow, inHi
End Sub

然后我使用 F8 键逐行浏览它,令我惊讶的是,它反复突出显示 End Sub 行,因为最后一个 If 语句为假,然后跳回到最后一个 If 语句,其中 tmpLow 和 inHi 的值变了!

我正在使用此网页中的数组值来尝试将第一部分中给出的逐行输出与中间的枢轴相匹配:https://www.bogotobogo.com/Algorithms/quicksort.php

我的实现与网页匹配,直到需要交换 7 和 5。此时变量具有以下值:

inLow = 0
inHi = 2
tmpLow = 2
tmpHi = 0

如您所见,两个 If 语句都不为真,因此该行传递到 End Sub。如果我再按一次 F8,突出显示会跳到最后一个 If 语句,并且变量现在具有值:

inLow = 0
inHi = 4
tmpLow = 3
tmpHi = 2

在算法的完整运行过程中会发生多次。我以前从未见过这种情况,也无法解释代码如何从 End Sub 上升,以及变量值如何在不执行任何明显代码的情况下发生变化。

如果您能帮我解决这个问题,我将不胜感激。

谢谢,

西蒙。

【问题讨论】:

你知道最后两个 if 语句递归调用 Quicksort Sub 吗? 【参考方案1】:

以下代码行递归调用SubQuickSort

  If (inLow < tmpHi) Then QuickSort vArray, inLow, tmpHi
  If (tmpLow < inHi) Then QuickSort vArray, tmpLow, inHi

这意味着它在完成之前从它自己的代码中调用SubQuickSort

如果发生这种情况,则构建所谓的调用堆栈。此堆栈包含已调用但尚未完成的程序。它保存了此时变量的值。

您可以使用 Locals window 中的按钮 ... 查看此调用堆栈。

现在,如果当前正在运行的 Sub QuickSort 已完成,但调用堆栈中有 Sub 的条目,则必须继续这些条目。为此,进程指针会跳转到递归调用Sub 的代码点。这将是If (inLow &lt; tmpHi) Then QuickSort vArray, inLow, tmpHi 行或If (tmpLow &lt; inHi) Then QuickSort vArray, tmpLow, inHi 行。将恢复也放入堆栈的其他所有变量值。然后堆叠的Sub 从那一点继续运行。依此类推,直到堆栈不再包含 Sub QuickSort。这就是递归的工作原理。

【讨论】:

非常感谢 Axel,您的回答简洁明了。我知道数学意义上的递归函数,但没有研究过它们如何在代码中工作。我不知道调用堆栈或本地窗口中该按钮的用途。对我来说都是很好的学习。碰巧,出于我不会让您感到厌烦的原因,我希望将算法编写为“在线” - 也就是说,不是作为一个单独的函数被调用,而是作为使用循环来完成排序的内联代码.我显然需要根据你教给我的内容来复习。问候。

以上是关于了解快速排序算法如何在 VBA 中重现的主要内容,如果未能解决你的问题,请参考以下文章

面试必备排序算法 --快速排序

快速排序的算法

经典算法复习快速排序的应用

数据结构 8 基础排序算法详解快速排序的实现了解分治法

快速排序算法的简单理解

C语言,快速排序算法