假设我们有一个列表:
a = [4, 8, 1, 7, 3, 0, 5, 2, 6, 9]
现在,a.sort()会就地排序列表。如果我们想要只对列表的一部分进行排序,同时仍然就地排序,该怎么办?在C++中,我们可以这样写:
int array = { 4, 8, 1, 7, 3, 0, 5, 2, 6, 9 };
int * ptr = array;
std::sort( ptr + 1, ptr + 4 );
在Python中有类似的方法吗?
假设我们有一个列表:
a = [4, 8, 1, 7, 3, 0, 5, 2, 6, 9]
现在,a.sort()会就地排序列表。如果我们想要只对列表的一部分进行排序,同时仍然就地排序,该怎么办?在C++中,我们可以这样写:
int array = { 4, 8, 1, 7, 3, 0, 5, 2, 6, 9 };
int * ptr = array;
std::sort( ptr + 1, ptr + 4 );
在Python中有类似的方法吗?
我会这样写:
a[i:j] = sorted(a[i:j])
这也不是原地排序,但对于相对较小的数据段来说速度足够快。
请注意,Python仅复制对象引用,因此与实际原地排序相比速度惩罚不会太大,正如人们所期望的那样。
如果a
是一个numpy
数组,要原地排序[i, j)
范围内的元素,那么请输入以下代码:
a[i:j].sort()
示例:
>>> import numpy as np
>>> a = np.array([4, 8, 1, 7, 3, 0, 5, 2, 6, 9])
>>> a[1:4].sort()
>>> a
array([4, 1, 7, 8, 3, 0, 5, 2, 6, 9])
array[start:end] = sorted(arr[start:end])
相比,快速排序的优点是不需要任何额外的内存,而分配给切片需要O(n)的额外内存。import random
def quicksort(arr, start , stop):
if(start < stop):
pivotindex = partitionrand(arr, start, stop)
quicksort(arr , start , pivotindex - 1)
quicksort(arr, pivotindex + 1, stop)
def partitionrand(arr , start, stop):
randpivot = random.randrange(start, stop)
arr[start], arr[randpivot] = arr[randpivot], arr[start]
return partition(arr, start, stop)
def partition(arr,start,stop):
pivot = start # pivot
i = start + 1 # a variable to memorize where the
# partition in the array starts from.
for j in range(start + 1, stop + 1):
if arr[j] <= arr[pivot]:
arr[i] , arr[j] = arr[j] , arr[i]
i = i + 1
arr[pivot] , arr[i - 1] = arr[i - 1] , arr[pivot]
pivot = i - 1
return (pivot)
array = [4, 8, 1, 7, 3, 0, 5, 2, 6, 9]
quicksort(array, 2, 6)
print(array)
sort
函数几乎总是更好。 - undefined