【问题标题】:QuickSort Dijkstra 3-Way Partitioning: why the extra swapping?QuickSort Dijkstra 3-Way Partitioning:为什么需要额外的交换?
【发布时间】:2014-03-08 09:48:39
【问题描述】:

给定这里的算法,看看我在“X”的场景,会发生以下情况:

场景: i -> "X", "X" > "P"

1. swap("X", "Z"), gt--;   // the value at i is now "Z", which is still > "P"
2. swap("Z", "Y"), gt--;   // the value at i is now "Y", which is still > "P"
3. swap("Y", "C"), gt--;    // Now we finally get a value at i "C" which is < "P"
// Now we can swap values at i and lt, and increrement them
4. swap("P", "C"), i++, lt++;

为什么我们不直接递减 gt 直到 gt 指向的值

因此,如果我们针对上述场景这样做,我们会这样做:

1. gt--
2. gt--
3. swap("X", "C"), gt--;   
// Now we can swap values at i and lt, and increrement them
4. swap("P", "C"), i++, lt++;

算法是否需要这种过度交换?它会以某种方式提高性能吗? 如果它确实提高了性能,如何?

如果不影响性能,请给出适当的解释或证明,说明为什么它不会影响性能。

另外,我提到的第二种方法会以任何方式影响性能吗?请解释原因。

附:上面使用的“影响性能”是指提高/降低性能。

【问题讨论】:

    标签: algorithm sorting quicksort


    【解决方案1】:

    你是对的,额外的交换操作不是必需的,这里的算法是为了清晰,而不是为了性能。见Quick Sort (3 Way Partition)的讨论。

    在 Robert Sedgewich 本人的Quicksort is optimal 中,他有一种不同的方法,它使用的交换操作要少得多,但您可以想象它也需要更多的代码,并且不如演示中的算法清晰。

    【讨论】:

      【解决方案2】:

      该算法基于 Dijkstra 对“荷兰国旗问题”的解决方案,该解决方案出现在他 1976 年出版的“A Discipline of Programming”一书中(第 111 页)。Dijkstra 编写这本书的目标是推导出可证明的正确性多个问题的解决方案。不只是呈现最终结果,而是实际经历设计过程。

      在“荷兰国旗的问题”中,Dijkstra 设想了一排桶(想想阵列),每个桶都包含一块鹅卵石,颜色为红色、白色或蓝色(荷兰国旗的颜色)。有一台只有两个操作的微型计算机。它可以交换两个桶的内容,并且可以检查桶中鹅卵石的颜色。他将后一种操作的使用限制为对每个存储桶进行一次检查。后者就足够了,因此他选择了他一贯的优雅简约风格。在证明正确性方面,考虑尽可能少的情况绝对是一个优势。以下是他的一篇著作中的一句话:“......一旦发现自己面临必须区分大量案例的案例分析,就会变得非常怀疑”。

      转换为排序问题,相当于最多进行 N 次比较。这其实很常见。在 C++ 标准中,不同排序算法和堆操作的复杂性取决于比较次数。不是交换的数量。想法是交换很便宜,如果不使用间接(指针)使其便宜。然而,比较可能会很昂贵。因此,用比较次数来说明复杂性更有意义。

      是的,您可以减少交换次数,但如果您希望最多进行 N 次比较,则不能。

      【讨论】:

        猜你喜欢
        • 2013-06-09
        • 2012-09-16
        • 1970-01-01
        • 2015-08-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多