简体   繁体   English

python中的quicksort和递归

[英]quicksort and recursion in python

I'm trying to implement quicksort in Python using 2 main functions - partition and quicksort. 我正在尝试使用2个主要功能-分区和快速排序在Python中实现快速排序。 The partition function is designed so that it returns 2 arrays - bigger and smaller than p. 设计了分区函数,使其返回2个数组-大于和小于p。 after that quicksort is called on both of them separately. 之后,将分别对它们进行快速排序。 so the quicksort works like this: 因此,快速排序的工作方式如下:

def quicksort(array)
    pivot = 0 # pivot choice is irrelevant
    left,right = partition(array,pivot)
    quicksort(left)
    quicksoft(right)
    return left+right

But from my understanding it should be possible to design partition to return just one single index - delimiting bigger and smaller arrays and redesign quicksort as follows: 但是据我所知,应该可以设计分区以仅返回一个索引-划定越来越大的数组并按如下方式重新设计quicksort:

def quicksort(array)
    pivot = 0 # pivot choice is irrelevant
    i = partition(array,pivot)
    quicksort(array[:i-1])
    quicksoft(array[i:])
    return array

but this implementation returns partially sorted array 但是此实现返回部分排序的数组

original array [5, 4, 2, 1, 6, 7, 3, 8, 9]
sorted array [3, 4, 2, 1, 5, 7, 6, 8, 9]

what am i missing here? 我在这里想念什么?

without seeing your code it's hard to be sure, but one possible error is the i-1 : 没有看到您的代码很难确定,但是i-1可能是一个错误:

>>> [1,2,3,4][:2]
[1, 2]
>>> [1,2,3,4][2:]
[3, 4]

(although you may be simply skipping the pivot?) (尽管您可能只是跳过了关键点?)

also, slices are new lists, not views: 同样,切片是新列表,而不是视图:

>>> l = [1,2,3,4]
>>> l[2:][0] = 'three'
>>> l
[1, 2, 3, 4]

which is unfortunate (the typical functional program doing quicksort which is not a quicksort at all, dammit, because it's creating a pile of new arrays annoys me too...) 这是不幸的(该死的典型的函数程序执行的quicksort根本不是quicksort,因为它正在创建一堆新数组,这也让我很烦...)

you can work round the second problem by passing the entire list plus lo/hi indices: 您可以通过传递整个列表以及lo / hi索引来解决第二个问题:

def quicksort(data, lo=0, hi=None):
    if hi is None: hi = len(data)
    ....

quicksort(array[:i-1]) doesn't actually call quicksort on the first partition of the array, it calls quicksort on a copy of the first partition of the array. quicksort(array[:i-1])实际上并没有在数组的第一个分区上调用quicksort,而是在数组的第一个分区的副本上调用了quicksort。 Thus, your code is partitioning the array in place, then creating copies of the halves and trying to sort them (but never doing anything with the resulting arrays), so your recursive calls have no effect. 因此,您的代码将数组分区到位,然后创建两半的副本并尝试对它们进行排序(但不要对结果数组进行任何操作),因此递归调用无效。

If you want to do it like this, you'll have to avoid making copies of the list with slicing, and instead pass around the whole list as well as the ranges you want your functions to apply to. 如果要这样做,就必须避免使用切片制作列表的副本,而要传递整个列表以及要应用函数的范围。

I had the same problem, my quicksort was returning partially sorted lists. 我遇到了同样的问题,我的快速排序返回了部分排序的列表。 I found the problem was that I wasn't returning the pivot in it's own array. 我发现问题是我没有在它自己的数组中返回数据透视表。 When I create an array for the pivot, it allows the recursion to work properly. 当我为枢轴创建数组时,它允许递归正常工作。

ie. 即。 my partition function returns instead of: 我的分区函数返回而不是:

return left, right 返回左,右

it returns 它返回

return left, pivotval, right 返回左,pivotval,右

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

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