【问题标题】:Swap condition in quick sort partition procedure (Lomuto)?快速排序分区程序(Lomuto)中的交换条件?
【发布时间】:2019-10-18 07:23:06
【问题描述】:

我已经实现了算法简介一书中的快速排序。本书规定的程序如下

但是我没有看到第 4 行的小于等于比较的要求,不应该只是小于比较就足够了

为了检查我是否编写了以下程序,并且它在我测试过的数据集上运行正确。

private fun partition(start: Int, end: Int, arr: Array<Int>) : Int{
        var pivotIndex = end
        var maximumElementIndex = start
        for(index in start until end){
            if(arr[index]<arr[pivotIndex]){
                val temp = arr[index]
                arr[index] = arr[maximumElementIndex]
                arr[maximumElementIndex] = temp
                maximumElementIndex++
            }
        }

        val temp = arr[maximumElementIndex]
        arr[maximumElementIndex] = arr[pivotIndex]
        arr[pivotIndex] = temp
        return maximumElementIndex
    }

我已经在以下输入上对其进行了测试

  • 元素全部相等的数组
  • 排序数组
  • 反向排序
  • 多个随机数据集

那么我在这里缺少什么?

【问题讨论】:

  • 您的“随机数据集”测试是否专门包括具有多个重复项的数组?
  • @JimMischel 是的,我用过这个(1,5,5,5,3,4,1,2,2,2,3,4,5,1),输出是正确的排序
  • 必须仔细构建测试用例,并了解分区的工作原理。分区中重复项的位置可能会影响事物。因此,除非您的测试用例涵盖所有可能性,否则无法确定。我以前见过这种情况,导致一个严重的错误逃逸到生产环境。用少数案例进行测试并不能替代检查算法并充分理解其行为。除非您完全理解,否则将&lt;= 比较留在那里。它不需要任何费用。
  • @JimMischel 我正在寻找关于为什么需要

标签: algorithm sorting quicksort


【解决方案1】:

除了使用&lt;= 之外,还有更多不同之处。它也在初始化i = p-1;,最终的交换是swap(A[i+1], A[r]);。这只是 Lomuto 分区方案的一种变体。您的示例代码与 Wiki 文章中的代码相匹配:

https://en.wikipedia.org/wiki/Quicksort#Lomuto_partition_scheme

请注意,对于已排序的数据、反向排序的数据和所有相等的元素,这两种方案都是最坏的情况,因为分区仅在每个级别的递归中将分区的大小减少 1。使用中间值作为枢轴并将其交换到末尾可以解决排序或反向排序数据的问题,但随着相等元素数量的增加,Lomuto 通常会变得更糟。

使用中间元素的 Hoare 方案通常会随着重复次数的增加而变得更好。与主元值相等的元素进行不必要的交换,但随着重复数量的增加,分区会接近大小均匀分割的理想情况,并且缓存有助于处理不需要的交换。

https://en.wikipedia.org/wiki/Quicksort#Hoare_partition_scheme

【讨论】:

  • 我知道霍尔方案的效率。我只是想知道由于交换条件,我对 lumoto 方法的实现是否不正确
  • @mightyWOZ - 您的代码与 wiki 文章相同。这本书展示了 Lomuto 的变体。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-06-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-28
相关资源
最近更新 更多