[Hello World] 选择排序笔记

1. 选择排序原理

在未排序序列中,不断选择最小值放到未排序序列的最前面(升序)
selection-sortselection-sortselection-sortselection-sortselection-sortselection-sortselection-sortselection-sortselection-sortselection-sortselection-sortselection-sortselection-sortselection-sortselection-sortselection-sortselection-sort

2. 选择排序过程

1.指针先指向第一个数
2.用第一个数与后面的数比较,如果第一个数小,指针不动,如果后面的数小,指针指向后面那个数
3.重复2的操作,直到把所有数遍历一遍找出了最小值
4.将最小值与第一个数交换位置
5.在未排序数列中重复2、3、4的操作

3. 代码

def selection_sort(our_list):
    length = len(our_list)
    for i in range(length - 1):
        # 1. 指针先指向第一个数
        min = i
        # 2. 用第一个数与后面的数比较,如果第一个数小,指针不动,如果后面的数小,指针指向后面那个数
        # 3. 重复2的操作,直到把所有数遍历一遍找出了最小值
        for j in range(i + 1, length):
            if our_list[j] < our_list[min]:
                min = j
        # 4. 将最小值与第一个数交换位置
        our_list[min], our_list[i] = our_list[i], our_list[min]
    return our_list

4. 算法分析

时间复杂度:O(n2)
空间复杂度:O(1)
最好和最坏的时间复杂度都为 O(n2)
不稳定性:当比较的两项相等,可能仍会交换,改变原有的相对位置。

验证不稳定性:

列表元素是元组,元组第一项是需排序数的标记,第二项是需排序的数字。

def selection_sort_test(our_list):
    length = len(our_list)
    for i in range(length - 1):
        min = i
        for j in range(i + 1, length):
            if our_list[j][1] < our_list[min][1]:  # 比较元组的第二个元素
                min = j
        our_list[min], our_list[i] = our_list[i], our_list[min]
    return our_list

our_list = [(1, 4), (2, 4), (3, 2), (4, 5)]

print("unsort list:", our_list)
print("sorted list:", selection_sort(our_list))

输出为:

unsort list: [(1, 4), (2, 4), (3, 2), (4, 5)]
sorted list: [(3, 2), (2, 4), (1, 4), (4, 5)]

可开看到,(1,4)(2,4) 的相对位置改变了。

5. 优化改进

原始算法是在未排序序列中,不断选择最小值放到最前面(升序),优化思想是在未排序序列中,不断选择最小值和最大值分别放到未排序序列的两端,这样一轮排序中排了两个数,增加了排序效率。

def selection_sort_better(our_list):
    n = len(our_list)
    for i in range(n//2):
        min_mark = i
        max_mark = n-i-1
        for j in range(i+1, n-i):
            if our_list[j] < our_list[min_mark]:
                min_mark = j
        if min_mark != i:
            our_list[i], our_list[min_mark] = our_list[min_mark], our_list[i]

    for j in range(n-i-2, i, -1):
        if our_list[j] > our_list[max_mark]:
            max_mark = j
    if max_mark != n-i-1:
        our_list[n-i-1], our_list[max_mark] = our_list[max_mark], our_list[n-i-1]
	return our_list

6. 代码下载

全部代码下载地址

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章