我是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
的参数或使用非递归算法。)
答案 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()
,除了无需更改列表即可创建列表的排序副本。