选择排序:
基本原理:
1.选取第一个(或者最后一个)为基准,假定为最小值(最大值)。
2.遍历第二个至最后的元素,与第一个比较,选出比第一个小的元素中最小的那个,与第一个交换位置,以此类推。
3.时间复杂度为o(n^2):因为一共需比较n*(n-1)/2次,
空间复杂度为o(1):因为没有创建新的数组,
稳定性:是个稳定的算法,如果两个数字相等,比较完成后其顺序不会发生改变。
算法优化:
1.每轮比较选出2个值,一个最大值,一个最小值
代码如下:
import math
def select_sort(arr):
length = len(arr)
total_num = 0
# 外循环控制比较轮数,如3个元素的只需比较2轮,4个元素的需比较3轮
# 优化后每轮选出最大和最小值,则3个元素只需比较1轮,4个元素比较2轮
for i in range(math.ceil((length-1)/2)):
# 假定选取未排序数组中第一个元素为最小值,最后一个为最大值
least = i
highest = length-i-1
total_num += 1
# 首次比较保证最小值比最大值要小,否则互换
if arr[least] > arr[highest]:
arr[least], arr[highest] = arr[highest], arr[least]
# 从第二个元素开始遍历至倒数第二个元素,与第一元素进行比较,选出比第一个元素小的最小的那个元素,再进行交换,与最后一个元素进行比较,选出比最后一个元素大的最大的那个元素,再进行交换。
for j in range(i+1, length-i-1):
total_num += 1
if arr[least] > arr[j]:
least = j
if arr[highest] < arr[j]:
highest = j
arr[i], arr[least] = arr[least], arr[i]
arr[length-i-1], arr[highest] = arr[highest], arr[length-i-1]
print("总共比较了%d次。" % total_num)
return arr
if __name__ == '__main__':
lis = [8, 3, 4, 8, 6, 3, 9, 10, 12, 5, 5]
print(select_sort(lis))
# 默认情况比较了55次
# 优化后比较了30次