Hoare 的 Partition 原始方法和 ALGOL 代码 [已关闭]

问题描述 投票:0回答:1

所以我正在阅读快速排序wiki的霍尔分区部分,它说:

“关于这个原始描述,实现通常会做出微小但重要的变化。值得注意的是,下面提出的方案包括等于反转候选者之间的主元的元素(因此“大于或等于”和“小于或分别使用“等于”测试代替“大于”和“小于”;因为公式使用 do...while 而不是重复...until,这实际上是通过使用严格比较运算符来反映的”

我通读了维基部分和原始论文,但我不确定如何实现这个原始方法。原始方法中我不确定的部分是:

“Hoare 因此规定,在最后,包含枢轴元素(仍处于其原始位置)的子范围可以通过排除该枢轴来减小大小,然后(如果需要)将其与子范围交换最接近分离的元素;因此,确保快速排序的终止。”

看起来这个想法是将主元交换到一个点,然后在下一个排序中不包含该索引,但是使用此方法时我们如何知道实际主元值在哪里。你知道如何实现描述吗,比如 Tony Hoare 的 ALGOL 代码示例?

sorting quicksort hoare-logic
1个回答
0
投票

使用此方法时我们如何知道实际的枢轴值在哪里?

在每个分区步骤开始时,选择一个段范围内的随机指针作为枢轴元素的指针。一旦选择,它就是一个已知值。然后,如果在分区步骤期间,如果任一扫描指针到达段的边界,则检测到特殊情况,并且将枢轴与适当段的第一个或最后一个元素交换,并将枢轴指针更新为指向到它的新位置,如原始论文中所述。这意味着在分区步骤之后,指向枢轴的指针在特殊情况下从未更改或更新,仍然是已知指针,并且可以从下一个分区步骤中排除。

使用此方法需要在每次更新指针时检查边界,或者保存刚刚超出边界的元素并将其替换为哨兵值,该哨兵值将保证小于左侧的任何枢轴值并大于左侧的任何枢轴值右边,然后在分区步骤后恢复这些值。

对此方法的改进是将扫描更改为在等于主元的元素上停止,从而消除了边界检查或哨兵值的需要。代价是不需要交换等于主元的元素,并且等于主元的元素和主元本身可以在任何地方结束,因此不能从下一个分区步骤中排除任何元素。必须小心选择枢轴指针以及在下一个分区步骤中使用哪个指针作为分割线,以保证分区大小会减小。


你知道如何实现描述吗?

Tony Hoare 的分区 ALGOL 代码是算法 63,快速排序是算法 64,位于 ACM 文章的几页片段的第 321 页上:

https://dl.acm.org/doi/pdf/10.1145/366622.366642

注意:ALGOL 是一种传递引用语言,因此partition() 改变了I 和J 的值。F 是主元的索引,X 是主元的值。以

if I < F
开头的代码处理特殊情况,其中枢轴交换到左端,并且 I 递增以不包含枢轴。同样,以
if F < J
开头的代码处理特殊情况,其中枢轴被交换到右端,并且 J 被递减以不包含枢轴。

© www.soinside.com 2019 - 2024. All rights reserved.