通过直接选择排序可以初步明白时间复杂度和空间复杂度的概念,以及直接选择排序的思路
实现过程
现将一步一步的展现一个无序集合[2,1,5,3,7]
进行直接选择排序(本文升序)的过程.首先将该集合分为2个部分,第一个部分为有序集合,第二个部分为无序集合,那么此时有序集合是空的[]
,而无序集合为[2,1,5,3,7]
,通过依次遍历原集合([2,1,5,3,7]
)的每一个元素记为A,循环的每个元素都去和无序集合里的每个值(遍历无序集合)进行对比,找到当次无序集合里的最小值(需要遍历此时的无序集合)B,然后交换A和B的位置,这样B就能进入到有序集合,A被交换到了无序集合里.具体过程如下:
-
开始遍历原集合(此时有序集合为
[]
,无序集合为[2,1,5,3,7]
),将集合中的第1个元素取出[2]
,然后开始和剩下的无序集合([1,5,3,7]
)进行对比,不和全部无序集合对比是因为自身和自身对比没意义,所以我们从无序集合的第2个开始进行比大小,我们找到了[1,5,3,7]
里的[1]
,然后进行交换(2和1进行交换),此时原集合变为[1,2,5,3,7]
-
此时遍历出集合第2个元素(此时有序集合为
[1]
,无序集合为[2,5,3,7]
),将无序集合中的第1个元素取出[2]
(因为被交换所以第2次又是2,例子没选好,懒得改了),然后开始和剩下的无序集合([5,3,7]
)进行对比,我们从此时的无序集合[2,5,3,7]
的第2个开始进行比大小,我们发现[2,5,3,7]
里没有比2还小的元素了,所以不用进行交换,因为此时的2就是这一轮最小的元素,此时原集合变为[1,2,5,3,7]
-
此时遍历出集合第3个元素(此时有序集合为
[1,2]
,无序集合为[5,3,7]
),将无序集合中的第一个元素取出[5]
,然后开始和剩下的无序集合([3,7]
)进行对比,我们从此时的无序集合[5,3,7]
的第二个开始进行比大小,我们找到了[3,7]
里比5还小的元素[3]
,所以两个进行交换,此时原集合变为[1,2,3,5,7]
-
此时遍历出集合第4个元素(此时有序集合为
[1,2,3]
,无序集合为[5,7]
),将无序集合中的第一个元素取出[5]
,然后开始和剩下的无序集合([7]
)进行对比,我们从此时的无序集合[5,7]
的第二个开始进行比大小,我们发现[7]
里没有比5还小的元素了,所以不用进行交换,因为此时的5就是这一轮最小的元素,此时原集合变为[1,2,3,5,7]
-
此时遍历出集合第5个元素(此时有序集合为
[1,2,3,5]
,无序集合为[7]
),将无序集合中的第一个元素取出[7]
,然后开始和剩下的无序集合([]
)进行对比,我们从此时的无序集合已经是空集合了,所以不用进行交换,因为此时的7就是这一轮最小的元素,此时原集合变为[1,2,3,5,7]
-
此时集合已经排序完毕,排序结果就是最后的有序集合
[1,2,3,5,7]
,无序集合里已经没有元素了.
原理
通过例子可以看出,集合有多少个元素就得遍历多少遍,所以需要第1个关键值,记录遍历集合的游标(记为i),在遍历元素的同时需要去找当前无序集合里的最小值,所以还需要2个关键游标,当前最小元素的游标(k),无序集合里的游标(j). 通过遍历集合我们先获取到当前 默认最小元素的游标 k 的值, 然后在无序集合遍历寻找比 k 的值 还小的值,把无序集合的当前的j赋值给k一直更新到无序集合遍历完毕, 这个时候如果 k 不等于初始值了,说明无序集合里有最小值的出现,交换k(已经更新为无序集合里最小值的游标)和i(第1层遍历的游标)的值,然后游标i进入下一轮的循环.
代码
def selectSort(list: 'list') -> list:
for i in range(len(list)): #循环目标列表,此时的i为遍历集合的游标
k = i #把当前游标选为默认的最小元素的游标
for j in range(i+1, len(list)): #用k的值,去和当前无序集合里的每一个值进行对比,所以要循环此时的无序集合,因为无序集合里的第一个和游标i的值相等,所以没有进行比大小的意义,所以循环是从无序集合里的i+1开始
if list[j] < list[k]: #进行k的值和无序集合里j的值比大小
k = j #如果发现无序集合里有更小的,那就更新k的值(k是每轮当中最小值的游标,初始值是和无序集合里第1个相等)
if k != i: #如果k的最终值已经和k的初始值i不一致了,说明无序集合里有最小值
list[k],list[i] = list[i], list[k] #那么就要交换2个游标的值
return list #返回排好序的list
总结
空间复杂度为O(1),因为是在原数组内进行不断的交换,没有额外的空间占用.时间复杂度为O(n²),因为有嵌套循环,抛去常数后为n²的复杂度.直接选择排序只需要好好理解游标的概念即可.
本文作者: Bowen
本文链接: https://dangbowen.com/algorithm/sort/18e3fa36.html
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明出处!