【问题标题】:Finding the k-th smallest item with quicksort (Python)使用快速排序查找第 k 个最小的项目(Python)
【发布时间】:2016-02-22 13:34:30
【问题描述】:

我试图实现this videothis document 中讨论的算法。

我的快速排序代码,它依赖于选择 数组中的中间元素 作为枢轴(见下文),而不是上面文档作者使用的方法,它使用 数组中的第一个元素作为shown here in the video的主元。

显然,我的代码不起作用(最终会超出递归限制)。我想知道这是否是因为我的代码中有一些愚蠢的错误,或者只要我从中间选择支点,它就无法正常工作。

def partition(a, start, end):
    # I pick the pivot as the middle item in the array
    # but the algorithm shown in the video seems to
    # pick the first element in the array as pivot
    piv = (start + end) // 2
    pivotVal = a[piv]

    left = start
    right = end

    while left <= right:

        while a[left] < pivotVal:
            left += 1

        while a[right] > pivotVal:
            right -= 1

        if left <= right:
            temp = a[left]
            a[left] = a[right]
            a[right] = temp
            left += 1
            right -= 1

    return left


def quicksort(a, start, end, k):

    if start < end:
        piv = partition(a, start, end)

        if piv == (k - 1):
            print("Found kth smallest: " + piv)
            return a[piv]
        elif piv > (k - 1):
            return quicksort(a, start, piv, k)
        else:
            return quicksort(a, piv + 1, end, k)

myList = [54, 26, 93, 17, 77, 31, 44, 55, 20]
quicksort(myList, 0, len(myList) - 1, 3)
print(myList)

【问题讨论】:

  • 你检查过快速选择算法吗?
  • 您正在使用包含数组边界。你让这变得不必要的困难。使用 [start, end) 几乎可以更优雅地描述每个算法。
  • 你在partition函数中混合了aarr
  • @FaizHalde,是的。我做到了。我只是想用不同的方法尝试它,因为使用快速排序似乎更方便我记住这种方法。
  • @thefourtheye 感谢您指出这一点。我修正了错字。但是这个错字不是代码不起作用的问题。

标签: python algorithm quicksort


【解决方案1】:

如果您使用包含数组边界,这不是最方便的技巧,您必须将递归调用中的范围更改为 [start, piv - 1][piv + 1, end]

原因是,您正在重新考虑数组左侧的每个递归中的 piv 元素。

具有上述更改的代码运行时没有任何堆栈溢出错误。

EDIT 对于少数 k 值,输出不正确。您可能需要再次检查您的分区逻辑。

【讨论】:

  • 谢谢。我希望对这个算法有很好的了解的人(使用快速排序来找到第 k 个最小的项目)将确认是否可以从中心选择枢轴。我已经在没有找到第 k 个元素的上下文的情况下自行测试了我的快速排序分区逻辑,它工作正常。这就是为什么我决定询问 StackOverflow。再次感谢。
  • 中间枢轴绝对是可能的,因为我记得阅读了基于它的资源。我敢肯定,实施起来会非常混乱
  • @Faize Halde,啊……这有点让人放心。如果您还记得出处,请随时分享。 :) 谢谢!
猜你喜欢
  • 2021-01-06
  • 1970-01-01
  • 2017-06-23
  • 1970-01-01
  • 2021-09-05
  • 2021-06-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多