1. 選擇排序原理
在未排序序列中,不斷選擇最小值放到未排序序列的最前面(升序)
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