选择排序(Selection Sort)基本思想:
将序列分为两部分:前边
i - 1
个元素为已排序部分,后边n - i + 1
个元素为未排序部分。第i
趟排序从未排序部分n − i + 1 (i = 1, 2, …, n − 1)
个元素中选择一个值最小的元素与未排序部分最前面那个元素交换位置,即与整个序列的第i
个位置上的元素交换位置。如此下去,直到所有元素都变为已排序部分,排序结束。
简单来说,「选择排序算法」是在每一趟排序中,从未排序部分中选出一个值最小的元素,与未排序部分第 1
个元素交换位置,从而将该元素划分到已排序部分。
- 第
1
趟排序:- 无已排序部分,把第
1
~n
个元素(总共n
个元素)作为未排序部分。 - 遍历
n
个元素,使用变量min_i
记录n
个元素中值最小的元素位置。 - 将
min_i
与未排序部分第1
个元素(也就是序列的第1
个元素)交换位置。如果未排序部分第1
个元素就是值最小的元素位置,则不用交换。 - 此时第
1
个元素为已排序部分,剩余第2
~n
个元素(总共n - 1
个元素)为未排序部分。
- 无已排序部分,把第
- 第
2
趟排序:- 遍历剩余
n - 1
个元素,使用变量min_i
记录n - 1
个元素中值最小的元素位置。 - 将
min_i
与未排序部分第1
个元素(也就是序列的第2
个元素)交换位置。如果未排序部分第1
个元素就是值最小的元素位置,则不用交换。 - 此时第
1
~2
个元素为已排序部分,剩余第3
~n
个元素(总共n - 2
个元素)为未排序部分。
- 遍历剩余
- 依次类推,对剩余
n - 2
个元素重复上述排序过程,直到所有元素都变为已排序部分,则排序结束。
- 初始序列为:
[6, 2, 3, 5, 1, 4]
。 - 第
1
趟排序,无已排序部分,把[6, 2, 3, 5, 1, 4]
(总共6
个元素)作为未排序部分:- 遍历这
6
个元素,使用变量min_i
记录6
个元素中值最小(值为1
)的元素位置,也就是第5
个元素位置。 - 将
min_i
与未排序部分第1
个元素(也就是序列的第1
个元素)交换位置,就是将元素6
和元素1
交换位置。 - 此时
[1]
为已排序部分,剩余[2, 3, 5, 6, 4]
(总共5
个元素)为未排序部分。此时序列为[1, 2, 3, 5, 6, 4]
。
- 遍历这
- 第
2
趟排序,把[1]
作为已排序部分,把剩余[2, 3, 5, 6, 4]
(总共5
个元素)作为未排序部分。- 遍历剩余
5
个元素,使用变量min_i
记录5
个元素中值最小的元素位置,也就是第2
个元素位置。 - 因为值最小的元素位置
min_i
就是未排序部分第1
个元素,所以不用交换。 - 此时
[1, 2]
为已排序部分,剩余[3, 5, 6, 4]
(总共4
个元素)为未排序部分。
- 遍历剩余
- 依次类推,对剩余
4
个元素重复上述排序过程,直到所有元素都变为已排序部分,则排序结束。此时,序列变为[1, 2, 3, 4, 5, 6]
。
-
时间复杂度:$O(n^2)$。排序法所进行的元素之间的比较次数与序列的原始状态无关,时间复杂度总是
$O(n^2)$ 。- 这是因为无论序列中元素的初始排列状态如何,第
i
趟排序要找出值最小元素都需要进行n − i
次元素之间的比较。因此,整个排序过程需要进行的元素之间的比较次数都相同,为$∑^n_{i=2}(i - 1) = \frac{n(n−1)}{2}$ 次。
- 这是因为无论序列中元素的初始排列状态如何,第
-
选择排序适用情况:选择排序方法在排序过程中需要移动较多次数的元素,并且排序时间效率比较低。因此,选择排序方法比较适合于参加排序序列的数据量较小的情况。选择排序的主要优点是仅需要原地操作无需占用其他空间就可以完成排序,因此在空间复杂度要求较高时,可以考虑选择排序。
-
排序稳定性:由于值最小元素与未排序部分第
1
个元素的交换动作是在不相邻的元素之间进行的,因此很有可能会改变值相同元素的前后位置,因此,选择排序法是一种 不稳定排序算法。
class Solution:
def selectionSort(self, arr):
for i in range(len(arr) - 1):
# 记录未排序部分中最小值的位置
min_i = i
for j in range(i + 1, len(arr)):
if arr[j] < arr[min_i]:
min_i = j
# 如果找到最小值的位置,将 i 位置上元素与最小值位置上的元素进行交换
if i != min_i:
arr[i], arr[min_i] = arr[min_i], arr[i]
return arr
def sortArray(self, nums: List[int]) -> List[int]:
return self.selectionSort(nums)