通过直接选择排序可以初步明白时间复杂度和空间复杂度的概念,以及直接选择排序的思路
实现过程
现将一步一步的展现一个无序集合[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进入下一轮的循环.
代码
1 | def selectSort(list: 'list') -> list: |
总结
空间复杂度为O(1),因为是在原数组内进行不断的交换,没有额外的空间占用.时间复杂度为O(n²),因为有嵌套循环,抛去常数后为n²的复杂度.直接选择排序只需要好好理解游标的概念即可.