Sort a part of a list in place
假设我们有一个列表:
1 | a = [4, 8, 1, 7, 3, 0, 5, 2, 6, 9] |
现在,a.sort()将对列表进行排序。 如果我们只想对列表的一部分进行排序,该怎么办? 在C ++中,我们可以编写:
1 2 3 | int array = { 4, 8, 1, 7, 3, 0, 5, 2, 6, 9 }; int * ptr = array; std::sort( ptr + 1, ptr + 4 ); |
Python中有类似的方法吗?
我会这样写:
1 | a[i:j] = sorted(a[i:j]) |
它也不是就地排序,但是对于相对较小的段来说足够快。
请注意,Python仅复制对象引用,因此与真正的就地排序相比,速度损失不会那么大。
如果
1 | a[i:j].sort() |
例:
1 2 3 4 5 | >>> 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]) |
要在两个索引之间进行排序,我建议使用quicksort。与
我不相信标准库中有实现,但是编写自己很容易。这是我从https://www.geeksforgeeks.org/quicksort-using-random-pivoting/复制并粘贴的实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | 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) |
为了在示例(包括范围)中的索引2和6之间进行排序,我将执行以下操作:
1 2 3 | array = [4, 8, 1, 7, 3, 0, 5, 2, 6, 9] quicksort(array, 2, 6) print(array) |