工作原理:
每一次從待排序的數據元素中選出最小(或最大)的一個元素,存放在序列的起始位置,直到全部待排序的數據元素排完。
穩定性:
選擇排序是不穩定的排序方法(比如序列[5, 5, 3]第一次就將第一個[5]與[3]交換,導致第一個5挪動到第二個5后面)。
時間復雜度:
比較次數O(n^2),比較次數與關鍵字的初始狀態無關,總的比較次數N=(n-1)+(n-2)+...+1=n*(n-1)/2。
交換次數O(n),最好情況是,已經有序,交換0次;最壞情況下,即待排序記錄初始狀態是按第一條記錄最大,之后的記錄從小到大順序排列,則需要移動記錄的次數最多為3(n-1),逆序交換n/2次。
空間復雜度:
O(1)。簡單選擇排序需要占用一個臨時空間,在交換數值時使用。
比較:
與插入排序比較:直接選擇排序和直接插入排序類似,都將數據分為有序區和無序區,所不同的是直接播放排序是將無序區的第一個元素直接插入到有序區以形成一個更大的有序區,而直接選擇排序是從無序區選一個最小的元素直接放到有序區的最后。選擇排序是固定位置,找元素。相比於插入排序的固定元素找位置,是兩種思維方式。
與冒泡排序比較:冒泡算法最費時的一是兩兩比較,二是兩兩交換,選擇排序中交換次數比冒泡排序少多了,n值較小時,選擇排序比冒泡排序快。
示例
代碼:
1 void Selectsort(int a[], int n) 2 { 3 int i, j, nMinIndex; 4 for (i = 0; i < n; i++) 5 { 6 nMinIndex = i; //找最小元素的位置 7 for (j = i + 1; j < n; j++) 8 if (a[j] < a[nMinIndex]) 9 nMinIndex = j; 10 11 Swap(a[i], a[nMinIndex]); //將這個元素放到無序區的開頭 12 } 13 } 14 15 inline void Swap(int &a, int &b) 16 { 17 int c = a; 18 a = b; 19 b = c; 20 }
注意swap交換,若如下不用中間變量,會有一個隱患,如果a, b指向的是同一個數,那么調用Swap1()函數會使這個數為0
1 inline void Swap1(int &a, int &b) 2 { 3 a ^= b; 4 b ^= a; 5 a ^= b; 6 }
這種情況下可以在Swap1()中加個判斷,如果二個數據相等就不用交換了
1 inline void Swap1(int &a, int &b) 2 { 3 if (a != b) 4 { 5 a ^= b; 6 b ^= a; 7 a ^= b; 8 } 9 }