選擇排序——直接選擇排序


 選擇排序 每一趟從待排序的元素中,選出最小的元素,放到已經排好序的序列的后面直到全部元素排序完畢。在這個過程中,有序區逐步擴大,而無序區逐漸縮小。

 

直接選擇排序

直接選擇排序是將無序區內的最小元素追加到有序區的后面,從而擴大有序區的范圍。而我們又是在原地排序,所有也就相當與交換無序區的第一個元素和無序區最小元素的位置。

我們需要一個游標來追蹤無序區的最小元素。 假設為 K ,

我們又同時假設每一趟排序前,無序區的第一個元素就是當前無序區的最小元素。 也就是說 k 在每一次排序開始時,都是指向無序區的第一個元素。

假設有這樣一個序列,最初整個序列都是無序的。k = 0; k指向6,我們假設6 是無序區里面最小的。(但這顯然是不可能的)

我們遍歷無序區所有元素,得到真正的最小元素的索引,賦值給k 然后將真正的最小元素和 無序區的第一個元素進行交換

如圖我們已經找到了無序區最小元素並完成了交換,同時有序區長度變為了1 

然后我們繼續我們的排序工作。此時k=1,k指向2,我們假設 2 就是整個無序區的最小元素

我們遍歷所有的無序區元素,發現,2還真是最小的元素。直接擴大有序區的范圍即可,不需要交換

繼續排序,k=2,k指向4,依舊遍歷所有無序區的元素,發現3才是真正最小的,於是將3 和4交換,有序區范圍再一次擴大

繼續,k=3,指向6,遍歷所有的無序區元素,發現4才是最小的,交換6 和4

繼續 k = 4,指向5 ,遍歷所有無序區的元素,發現5確實是最小的,擴大有序區的范圍

k=5,指向6,發現6就是最大的了

有序區擴大到整個序列,排序完成。

 

 代碼如下:

def select_sort(A,n):
    for i in range(n):   #  無序區的范圍是 [0,n-1]
        k = i    #確定每次循環 k 的初始值。仔細研究一下上圖會發現 每次循環 的 i 和 k 的值相等,都是當前無序區的第一個元素的索引
        for j in range(i+1,n):  # 已經假設 k 指向的就是最小元素,但實際可能並不是,因此從無序區的第二個元素開始遍歷所有剩余的元素,(也可以從i 開始,也就是說,從無序區的第一個元素開始,但是 k 本身就是無序區的第一個元素,它永遠不可能比他自己小,所以無序區的第二個元素開始查找比較好)
            if A[k]>A[j]:   #如果正在遍歷的元素小於 k 指向的元素
                k = j     #那么就移動 k ,知道所有的剩余元素都遍歷完,這時候才能確定真正的 k 的位置。
        if k != i:  # 這里判斷 k 是否等與 i 的作用是為了減少操作量,就像 上圖里面k=1的時候,發現它確實就是最小的,因此就沒必要進行下面的操作。
            A[k],A[i]=A[i],A[k]  # 經過上面的查找已經找到了無序區真正的最小元素的索引,交換無序區最小元素和第一個元素。
    return  A

A=[6,2,4,1,5,3]
n =len(A)
print(select_sort(A,n))

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM