[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. 代碼下載

全部代碼下載地址

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