选择排序算法的原理:
选择排序是从冒泡排序演化而来的,每一轮(趟)比较出最小的那个值,放到第一个位置,然后在每轮的无序区中选出最小的值放到第二个位置。
目的:从小到大排序
图示:
算法的关键点是:有序区跟无序区、无序区最小的位置
首先我们写一个简单的选择排序,用到python的内置模块:
#思路是我们创建一个新列表,将原列表中的最小数选出后添加到新列表的中,实现排序。
#定义一个简单的选择排序
1 def select_sort_simple(li): 2 list_new = [] 3 for i in range(len(li)): 4 min_num = min(li) 5 list_new.append(min_num) 6 li.remove(min_num) 7 return list_new 8 9 li = [2,5,1,7,4,9,3,0] 10 print(select_sort_simple(li))
结果:[0, 1, 2, 3, 4, 5, 7, 9]
缺点:
-
我们生成了一个新的列表,原来需要1G内存的列表,现在需要2G内存,且复杂度增加
-
里面使用的min\remove复杂度都不是O(1),而是O(n),(remove(O(n)):remove删除元素后,后面元素需要补齐)-----该程序的复杂度为O(n^2)
回归主线,使用代码解释选择排序算法,我们的需求是什么===》不产生新列表,并且每趟将原列表无序区中最小的数放在第一个位置、第二个位置......
换种说法就是先找出原列表的最小值然后与列表的第一个位置上的元素进行交换。
最多需要N趟,每趟出来一个数,但是N-1趟结束后,无序区只剩一个数不要走一边,所以我们最多需要N-1趟,每一趟都需要便利无序区,无序区的范围是:第0趟:从0到最后,第1趟:从1到最后,.....所以无序区的范围:i+1 — len(i)。
我们还需要记录最小值的位置:min_loc = i(假定无序区的第一个位置为最小值)
1 #选择排序的优解 2 def select_sort(li): 3 for i in range(len(li)-1): 4 min_loc = i 5 for j in range(i+1,len(li)): 6 if li[j] < li[min_loc]: #无序区第一个数小于最小值 7 min_loc = j #赋值 8 li[min_loc],li[i] = li[i],li[min_loc] #两个数交换 9 print(li) 10 11 li = [2,5,1,7,4,9,3,0] 12 print(li) 13 select_sort(li)
结果:
1 [2, 5, 1, 7, 4, 9, 3, 0] 2 [0, 5, 1, 7, 4, 9, 3, 2] 3 [0, 1, 5, 7, 4, 9, 3, 2] 4 [0, 1, 2, 7, 4, 9, 3, 5] 5 [0, 1, 2, 3, 4, 9, 7, 5] 6 [0, 1, 2, 3, 4, 9, 7, 5] 7 [0, 1, 2, 3, 4, 5, 7, 9] 8 [0, 1, 2, 3, 4, 5, 7, 9]