选择排序算是对冒泡排序的一种改进:假设有n个待排列的数据,在第一轮遍历中,仍进行n - 1次比较,遍历的时候用当前数与当前获得的最大数进行比较,而不是相邻的数据进行比较,且仅进行一次数据交换。而冒泡排序在每一次比较的过程中,发现数据顺序不一致就交换,数据交换的次数更多。选择排序只需要用标记记住每一轮的最大数,然后与排序模式中该最大数应该待的位置进行一次数据交换。
废话不多说,直接看Python的实现代码:
def selection_sort(a_list):
for current_pass in range(len(a_list) - 1, 0, -1):
max_index = 0
for location in range(1, current_pass + 1):
if a_list[location] > a_list[max_index]:
max_index = location
temp = a_list[max_index]
a_list[max_index] = a_list[current_pass]
a_list[current_pass] = temp
我们在每一轮中用max_index记录当前比较的最大值的索引位置,然后用下一个数据与当前所标记的最大值进行比较,若比当前最大值还大,则更新最大值的索引。一轮遍历完成后,进行数据交换,将当前轮次确定的最大值与指定位置的值进行一次数据交换。
值得注意的是,选择排序不是一个稳定的排序算法。比如有 2 9 5 9 3这几个数,进行从小到大排序,第一轮遍历时,确定了第一个9是最大的数,然后和3进行交换,交换后的顺序为2 3 5 9 9。显然排序前和排序后的2个9的相对位置发生了交换,算法稳定性遭到破坏。
有人可能会问,如果将if语句的>改为>=,那么第一轮遍历的时候第二个9就会与3进行交换,从而保证了第二个9在整体排序后依然排在第一个9的右边,从而保证了算法的稳定性。但不幸的是朋友,你错了。我们依然按照上面的例子,只是这次变成2 1 9 3 3,按照>=就交换最大值的原则,那么第一轮遍历时,9和最右边的3交换,从而破坏了2个3之间的相对顺序。而第二轮由于使用了>=,则2个3的相对顺序又没有改变回来。所以,不管是>还是>=就交换最大值,稳定性都有几率遭到破坏,故选择排序是一种不稳定的排序算法。