1. 程式人生 > >Python全棧-magedu-2018-筆記11

Python全棧-magedu-2018-筆記11

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