Python全棧-magedu-2018-筆記11
阿新 • • 發佈:2019-04-30
mage 簡單選擇排序 遍歷 判斷 當前 優點 開始 ini src
第三章 - Python 內置數據結構
簡單選擇排序
- 簡單選擇排序
- 屬於選擇排序
- 兩兩比較大小,找出極值(極大值或極小值)被放置在固定的位置,這個固定位置一般指的是某一端
- 結果分為升序和降序排列
- 降序
- n個數從左至右,索引從0開始到n-1,兩兩依次比較,記錄大值索引,此輪所有數比較完畢,將大數和索引0數交換,如果大數就是索引1,不交換。第二輪,從1開始比較,找到最大值,將它和索引1位置交換,如果它就在索引1位置則不交換。依次類推,每次左邊都會固定下一個大數。
- 升序
- 和降序相反
簡單選擇排序
簡單選擇排序代碼實現(一)*
m_list = [ [1, 9, 8, 5, 6, 7, 4, 3, 2], [1, 2, 3, 4, 5, 6, 7, 8, 9], [9, 8, 7, 6, 5, 4, 3, 2, 1] ] nums = m_list[1] length = len(nums) print(nums) count_swap = 0 count_iter = 0 for i in range(length): maxindex = i for j in range(i + 1, length): count_iter += 1 if nums[maxindex] < nums[j]: maxindex = j if i != maxindex: tmp = nums[i] nums[i] = nums[maxindex] nums[maxindex] = tmp count_swap += 1 print(nums, count_swap, count_iter)
簡單選擇排序代碼實現(二)
- 優化實現
二元選擇排序
同時固定左邊最大值和右邊最小值
優點:
減少叠代元素的次數
? 1、length//2 整除,通過幾次運算就可以發現規律
? 2、由於使用了負索引,所以條件中要增加
? i == length + minindex
? 還有沒有優化的可能?
count_swap = 0 count_iter = 0 # 二元選擇排序 for i in range(length // 2): maxindex = i minindex = -i - 1 minorigin = minindex for j in range(i + 1, length - i): # 每次左右都要少比較一個 count_iter += 1 if nums[maxindex] < nums[j]: maxindex = j if nums[minindex] > nums[-j - 1]: minindex = -j - 1 # print(maxindex, minindex) if i != maxindex: tmp = nums[i] nums[i] = nums[maxindex] nums[maxindex] = tmp count_swap += 1 # 如果最小值被交換過,要更新索引 if i == minindex or i == length + minindex: minindex = maxindex if minorigin != minindex: tmp = nums[minorigin] nums[minorigin] = nums[minindex] nums[minindex] = tmp count_swap += 1 print(nums, count_swap, count_iter)
簡單選擇排序代碼實現(二)
- 改進實現
如果一輪比較後,極大值、極小值的值相等,說明比較的序列元素全部相等
m_list = [ [1, 9, 8, 5, 6, 7, 4, 3, 2], [1, 2, 3, 4, 5, 6, 7, 8, 9], [9, 8, 7, 6, 5, 4, 3, 2, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1] ] nums = m_list[3] length = len(nums) print(nums) count_swap = 0 count_iter = 0 # 二元選擇排序 for i in range(length // 2): maxindex = i minindex = -i - 1 minorigin = minindex for j in range(i + 1, length - i): # 每次左右都要少比較一個 count_iter += 1 if nums[maxindex] < nums[j]: maxindex = j if nums[minindex] > nums[-j - 1]: minindex = -j - 1 # print(maxindex, minindex) if nums[maxindex] == nums[minindex]: # 元素全相同 break if i != maxindex: tmp = nums[i] nums[i] = nums[maxindex] nums[maxindex] = tmp count_swap += 1 # 如果最小值被交換過,要更新索引 if i == minindex or i == length + minindex: minindex = maxindex if minorigin != minindex: tmp = nums[minorigin] nums[minorigin] = nums[minindex] nums[minindex] = tmp count_swap += 1 print(nums, count_swap, count_iter)
簡單選擇排序代碼實現(二)
- 改進實現
[1, 1, 1, 1, 1, 1, 1, 1, 2] 這種情況,找到的最小值索引是-2,最大值索引8,上面的代碼會交換2次,最小值兩個1交換是無用功,所以,增加一個判斷
m_list = [
[1, 9, 8, 5, 6, 7, 4, 3, 2],
[1, 2, 3, 4, 5, 6, 7, 8, 9],
[9, 8, 7, 6, 5, 4, 3, 2, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 2]
]
nums = m_list[4]
length = len(nums)
print(nums)
count_swap = 0
count_iter = 0
# 二元選擇排序
for i in range(length // 2):
maxindex = i
minindex = -i - 1
minorigin = minindex
for j in range(i + 1, length - i): # 每次左右都要少比較一個
count_iter += 1
if nums[maxindex] < nums[j]:
maxindex = j
if nums[minindex] > nums[-j - 1]:
minindex = -j - 1
print(maxindex, minindex)
if nums[maxindex] == nums[minindex]: # 元素相同
break
if i != maxindex:
tmp = nums[i]
nums[i] = nums[maxindex]
nums[maxindex] = tmp
count_swap += 1
# 如果最小值被交換過,要更新索引
if i == minindex or i == length + minindex:
minindex = maxindex
# 最小值索引不同,但值相同就沒有必要交換了
if minorigin != minindex and nums[minorigin] != nums[minindex]:
tmp = nums[minorigin]
nums[minorigin] = nums[minindex]
nums[minindex] = tmp
count_swap += 1
print(nums, count_swap, count_iter)
簡單選擇排序總結
- 簡單選擇排序需要數據一輪輪比較,並在每一輪中發現極值
- 沒有辦法知道當前輪是否已經達到排序要求,但是可以知道極值是否在目標索引位置上
- 遍歷次數1,...,n-1之和n(n-1)/2
- 時間復雜度O(n2)
- 減少了交換次數,提高了效率,性能略好於冒泡法
最後
本文的另外鏈接是:https://herodanny.github.io/python-magedu-2018-notes11.html
Python全棧-magedu-2018-筆記11