經典排序算法 - 選擇排序Selection sort
顧名思意,就是直接從待排序數組里選擇一個最小(或最大)的數字,每次都拿一個最小數字出來,
順序放入新數組,直到全部拿完
再簡單點,對著一群數組說,你們誰最小出列,站到最后邊
然后繼續對剩余的無序數組說,你們誰最小出列,站到最后邊
再繼續剛才的操作,一直到最后一個,繼續站到最后邊,現在數組有序了,從小到大
效率稍高一些的排序【選擇排序】
選擇排序(Selection sort)是一種簡單直觀的排序算法。它的工作原理如下。首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再從剩余未排序元素中 繼續尋找最小(大)元素,然后放到已排序序列的末尾。以此類推,直到所有元素均排序完畢。
選擇排序的主要優點與數據移動有關。如果某個元素位于正確的最終位置上,則它不會被移動。選擇排序每次交換一對元素,它們當中至少有一個將被移到其 最終位置上,因此對n個元素的表進行排序總共進行至多n-1次交換。在所有的完全依靠交換去移動元素的排序方法中,選擇排序屬于非常好的一種。
簡要的說就是先取出或假設一個最小或最大的數,之后在剩下的數里挑選一個最小或最大的,再和我們認為的最小或最大的數比較。滿足條件就交換位置
舉例
先說看每步的狀態變化,后邊介紹細節,現有無序數組[6 2 4 1 5 9]
第一趟找到最小數1,放到最前邊(與首位數字交換)
交換前:| 6 | 2 | 4 | 1 | 5 | 9 |
交換后:| 1 | 2 | 4 | 6 | 5 | 9 |
第二趟找到余下數字[2 4 6 5 9]里的最小數2,與當前數組的首位數字進行交換,實際沒有交換,本來就在首位
交換前:| 1 | 2 | 4 | 6 | 5 | 9 |
交換后:| 1 | 2 | 4 | 6 | 5 | 9 |
第三趟繼續找到剩余[4 6 5 9]數字里的最小數4,實際沒有交換,4待首位置無須交換
第四趟從剩余的[6 5 9]里找到最小數5,與首位數字6交換位置
交換前:| 1 | 2 | 4 | 6 | 5 | 9 |
交換后:| 1 | 2 | 4 | 5 | 6 | 9 |
第五趟從剩余的[6 9]里找到最小數6,發現它待在正確的位置,沒有交換
排序完畢輸出正確結果[1 2 4 5 6 9]
第一趟找到最小數1的細節
當前數組是| 6 | 2 | 4 | 1 | 5 | 9 |
先把6取出來,讓它扮演最小數
當前最小數6與其它數一一進行比較,發現更小數就交換角色
當前最小數6與2比較,發現更小數,交換角色,此時最小數是2,接下來2與剩余數字比較
當前最小數2與4比較,不動
當前最小數2與1比較,發現更小數,交換角色,此時最小數是1,接下來1與剩余數字比較
當前最小數1與5比較,不動
當前最小數1與9比較,不動,到達末尾
當前最小數1與當前首位數字進行位置交換,如下所示
交換前:| 6 | 2 | 4 | 1 | 5 | 9 |
交換后:| 1 | 2 | 4 | 6 | 5 | 9 |
完成一趟排序,其余步驟類似
代碼僅供參考
復制代碼
static void selection_sort(int[] unsorted)
{
for (int i = 0;? i < unsorted.Length-1; i++)//1、外層循環的結束條件不妥,因為循環排序到最后一個就是最大/小值了,不需要在進行比較,所以應該去除
{
int min = unsorted[i], min_index = i;
for (int int j = i+1; j < unsorted.Length; j++)//2、內層循環的初始條件不妥,如果從i開始就是和自身進行比較了,多余
{
if (unsorted[j] < min)
{
min = unsorted[j];
min_index = j;
}
}
if (min_index != i)
{
int temp = unsorted[i];
unsorted[i] = unsorted[min_index];
unsorted[min_index] = temp;
}
}
}
static void Main(string[] args)
{
int[] x = { 6, 2, 4, 1, 5, 9 };
selection_sort(x);
foreach (var item in x)
{
Console.WriteLine(item);
}
Console.ReadLine();
}
排序法 ?最差時間分析 平均時間復雜度 穩定度 空間復雜度
選擇排序 O(n2) O(n2) 穩定 O(1)