如何使这种快速排序实现有效?

时间:2019-01-09 15:07:04

标签: python slice quicksort

我是C ++开发人员,是Python的新手。我想在python中实现快速排序,这是我的代码:

from typing import Sequence, MutableSequence

def find_if(list: Sequence, predicate):
    """Find first element of the list which predicate return true"""
    for i in range(len(list)):
        if predicate(list[i]):
            return i
    return None

def find_if_not(list: Sequence, predicate):
    return find_if(list, lambda x : not predicate(x))

def partition(list: MutableSequence, predicate):
    """Reorder elements in list in such away that all element which the predicate
    return `true` precede the elements for which predicate returns false. Return
    value is index of the first element in the second group"""
    first = find_if_not(list, predicate)
    if first == None:
        return first

    for i in range(first+1, len(list)):
        if predicate(list[i]):
            list[i], list[first] = list[first], list[i]
            first = first + 1

    return first

def quick_sort(list: MutableSequence, key = lambda x : x):
    if len(list) <= 1:
        return

    pivot = list[0]
    last1 = partition(list, lambda x : x < pivot)
    first2 = partition(list[last1:], lambda  x : x == pivot)

    quick_sort(list[0:last1])
    if first2:
        quick_sort(list[first2:])

if __name__ == '__main__':
    arr = [6, 4, 7, 2, 8, 1, 3, 5, 2, 10, 13, 124, 1, 7]
    result = sorted(arr)
    quick_sort(arr)
    print("My sorted array: ", arr)
    print("Corrected result: ", result)

结果不正确。我认为问题是list[0:last1]list[first2:]复制而不是引用列表中的元素。我该如何进行这项工作? (我不想将索引范围作为quick_sort的参数或使用非递归算法。)

1 个答案:

答案 0 :(得分:1)

您是正确的-在python中称为 list切片,它会在原始切片处返回原始列表的副本。就quicksort而言,最简单的解决方案是只使用列表串联。而不是从quicksort返回None,而是返回已排序的列表。然后,将左边的列表和右边的列表连接起来,并用它们之间的支点:

def quick_sort(list: MutableSequence, key = lambda x : x):
    if len(list) <= 1:
        return list

    ...

    return quick_sort(list[:last1]) + [pivot] + quick_sort(list[first2:])

请注意,quick_sort在提供空列表时将返回一个空列表,因此在这种情况下无需使用if语句。这也是使用 quicksort时您将要采用的方法-许多python的字符串操作和列表操作都是非可变的,而my_list = quick_sort(my_list)my_list.sort(),除了无需更改列表即可创建列表的排序副本。