前言
前面幾篇分享了插入排序和交換排序,接下來說說選擇排序~~~
選擇排序(Selection sort):每一趟在待排序元素中選取元素值最小(或最大)的元素加入有序子序列。即在一堆資料中,每次挑出最小的或最大的放入其他有序序列中,當選擇完所有待排序資料時,排序就完成了。
選擇排序有兩種:簡單選擇排序和堆排序;接下來就從簡單的開始,先來說說簡單選擇排序。
正文
1.1 簡單選擇排序演算法思想
簡單選擇排序很直觀,直接從待排序列表中找出最小(或最大)的元素放到有序序列中,直到待排序列表中的元素被選擇完為止。
演算法思想
- 在待排序列表中找出最小(或最大)的元素;
- 將找出的元素放到有序序列中;
- 重複以上步驟,直到待排序列表中元素被選擇完為止。
1.2簡單選擇排序演算法實現與解析
-
演算法實現
-
執行效果
-
步驟解析(升序):
上圖步驟說明:
圖中黃色方塊是標記最小元素的位置,紅色方塊是代表待排序列表中下一個要比較的元素,綠色方塊代表有序序列,剛開始有序序列中可以認為沒有元素。上述案例演示中共六個元素,需要進行五趟(n-1)排序,如下:
第一趟排序
第1.1步,此時有序序列中認為沒有元素,標記0索引位為最小元素位置,開始依次比較待排序列表中後面的每一個元素,先比較元素5, 5大於2,最小元素標記位不變,繼續比較;
第1.2步,接著用標記的最小位元素2與元素6比較,6大於2,最小元素標記位不變,繼續比較;
第1.3步,接著用標記的最小位元素2與元素1比較,1小於2,需要改變最小元素標記位,此時最小元素的標記位為1的索引位,即min為3,然後繼續比較;
第1.4步,接著用標記的最小位元素1與元素9比較,9大於1,最小元素標記位不變,繼續比較;
第1.5步,接著用標記的最小位元素1與元素3比較,3大於1,最小元素標記位不變,繼續比較;
第1.6步,待排序列表遍歷完成,找到最小元素索引位為3,即元素1,則需要把元素1放到有序序列中,這裡就直接放在待排序列表前面,只需將第一個元素和得到的最小元素交換位置即可,此時有序序列中的元素有一個1;
第二趟排序
經過第一趟排序,有序序列中有一個元素,即當前整個陣列的第一個元素(綠色方塊);接下來繼續在待排序列表中找最小的元素加入到序列中。
第2.1步,第二趟剛開始標記1索引位為最小元素位置,然後依次比較後面的每一個元素,先比較元素6,6大於5,最小標記位不變,繼續比較;
第2.2步,接著用標記的最小位元素5與元素2比較,2小於5,需要改變最小元素標記位,此時最小元素的標記位為2的索引位,即min為3,然後繼續比較;
第2.3步,接著用標記的最小位元素2與元素9比較,9大於2,最小元素標記位不變,繼續比較;
第2.4步,接著用標記的最小位元素2與元素3比較,3大於2,最小元素標記位不變,繼續比較;
第2.5步,待排序列表遍歷完成,找到最小元素索引位為3,即元素2,則需要把元素2加入到有序序列中,這裡還是接著上一趟排序得到有序序列往後放,只需將第二個元素5和得到的最小元素2交換位置即可,此時有序序列中的元素有兩個(即1,2);
第三趟、第四趟、第五趟就不詳細寫步驟啦,重複上面步驟即可,直到待排序列表中的元素被選擇完為止,這樣就得到最終的排序結果啦。
1.3 簡單選擇排序演算法分析
-
時間複雜度
不管待排序列表是有序、逆序還是亂序,如果待排序列表中如果有個n個元素,就得需要n-1趟處理才能得到最終的結果,則在其中比較大小的次數為:(n-1)+(n-2)+(n-3)+...+1,而對於其中交換元素的次數小於n-1次,則根據時間複雜度表示形式,去除常數和係數,取高階進行表示,則簡單選擇排序的時間複雜度為O(n2)。
-
空間複雜度
在核心排序過程中只採用了固定的幾個中間變數(min,i,j,temp),則空間複雜度為O(1)。
-
穩定性
在選擇排序過程中,兩個元素相等,但還是有可能交換位置,則簡單排序演算法不穩定,如下:
在上圖中,黃色方塊2會先標記為最小位,依次往後進行比較找到真實的最小位的元素為白色方塊1,則需要將白色方塊1放到前面有序序列中,其實就是和黃色方塊2進行位置交換,這樣最終就會導致原來兩個相等元素2的順序發生改變,則簡單選擇排序為不穩定演算法。
綜上所述,簡單選擇排序的時間複雜度為O(n2),空間複雜度為O(1),是不穩定演算法。
總結
看完簡單選擇排序,小夥伴會覺得和直接插入排序很像,但是他們有一個很大區別,簡單選擇排序是將已經得到的最小(或最大)元素依次放入到有序序列中,而直接插入排序是在從待排序列表中直接取出一個元素,然後在和原來有序列表中元素進行比較,找到對應位置,然後插入到對應位置。
對比以往排序演算法的經驗,簡單選擇排序演算法的元素比較次數還是可以優化的,所以下一次來說說比較難搞的堆排序。
一個被程式搞醜的帥小夥,關注"Code綜藝圈",跟我一起學~~~