__author__ = 'steven'
# coding=utf-8
'''注意:“交换”是个比较耗时的操作!'''
'''选择排序
选择排序相比冒泡,大大减少了元素的交换次数.
其实我们很容易发现,在还未完全确定当前最小元素之前,这些交换都是无意义的。
我们可以通过设置一个变量min,然后每一次子循环中,仅存储较小元素的数组下标,
当前子循环结束之后,那这个变量存储的就是当前子循环最小元素的下标,此时再执行交换操作即可。
第 1 次遍历 n-1 个数,找到最小的数,然后与第 1 个数交换;
第 2 次遍历 n-2 个数,找到最小的数,然后与第 2 个数交换;
... ...
第 n-1 次遍历 1 个数,找到最小的数,然后与第 n-1 个数交换;
== 如果外层循环为 range(n-1),则没有第n次遍历;
如果外层为 range(n),则有第n次遍历,但是子循环条件为 range(n,n),仍为无效遍历.==
平均时间复杂度为 O(n^2),该算法不稳定.
'''
list = [5, 8, 1, 4, 2, 7, 3, 6]
# list_ascended = [1, 2, 3, 4]
# list_descended = [5, 4, 3, 2]
def select_sort(list):
n = len(list)
for i in range(n): # 参数为 n 和 n-1 都可以,本质上都是 n-1 次遍历
min = i # 记录当前最小数的序号(位置)
print(list)
for j in range(i + 1, n): # 以i+1为起点,0为终点,向后遍历
if list[j] < list[min]:
min = j # 记录当前最小数的序号
if min != i: # 将当前最小数放在子循环的开头
list[min], list[i] = list[i], list[min] # 每次只进行一次"交换"操作
return list
print(select_sort(list))
# print('-----')
# print(select_sort(list_ascended))
# print('-----')
# print(select_sort(list_descended))