简体   繁体   English

使用quicksort(Python)查找第k个最小项目

[英]Finding the k-th smallest item with quicksort (Python)

I was trying to implement the algorithm discussed in this video and also in this document . 我正在尝试实现此视频以及本文档中讨论的算法。

My quicksort code, which depends on picking the middle element in the array as the pivot (see below), as opposed to the approach used by the author of the document above, which uses the first element in the array as the pivot as shown here in the video . 我的快速排序代码依赖于选择数组中的中间元素作为枢轴(请参见下文),与上面文档的作者所使用的方法相反,该方法使用数组中的第一个元素作为枢轴,如此处所示在视频中

Obviously, my code doesn't work (runs out of the recursion limit eventually). 显然,我的代码不起作用(最终超出了递归限制)。 I wonder if it's because of some silly error in my code or that it simply would NOT work as long as I pick the pivot from the middle. 我想知道这是因为我的代码中出现了一些愚蠢的错误,还是只要我从中间选择了枢轴,它就根本无法工作。

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)

If you are using inclusive array bounds, which isn't the most convenient trick, you'll have to change the range in the recursive calls to [start, piv - 1] and [piv + 1, end] 如果使用包容数组边界(这不是最方便的技巧),则必须将递归调用中的范围更改为[start, piv - 1][piv + 1, end]

Reason being, you are reconsidering the piv element in the each recursion that goes to the left of array. 原因是,您要在数组左侧的每个递归中重新考虑piv元素。

The code with said changes ran without any stack overflow error. 具有上述更改的代码运行无任何堆栈溢出错误。

EDIT The output isn't right for few values of k. 编辑对于k的几个值,输出不正确。 You may need to check your partition logic again. 您可能需要再次检查分区逻辑。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM