- 選擇排序(Selection sort)是最基本的O(n^2)的排序算法,通過依次比較數組中前一個元素跟后一個元素的大小,來找到并記錄最小的那個元素的下標,再與第一個元素交換。以此類推,找到第二小的元素的下標,再與第二個元素交換,直到全部遍歷完成。
-
插入排序也是一個時間復雜度平均為O(n^2)的算法。
1.png
排序時首先第一個元素不動,因為我們認為它已經在正確的位置了。
接下來將第二位與第一位進行比較,如果比第一位小,則將二者交換。
此時前兩位完成。
然后繼續將第三位與前一位比較,如果比前一位小,交換二者。
再將第二位與前一位比較,比前一位大則結束,進行下一個元素排序,直到全部完成。
插入排序相比選擇排序不同的是,第二層循環可以提前結束,即與前一位比較時,比前一位大,就說明此時元素已經在正確的位置了,直接進行下一個循環。由于可以提前結束內循環,所以在再好的情況下,插入排序的時間復雜度可以達到O(n)的級別。
- 我們代碼測試一下。
首先我們定義可以一個生成隨機數數組的方法。
NSMutableArray* createDifferentArr (int count) {
NSMutableArray *arr = [[NSMutableArray alloc] init];
NSInteger random;
for (;;) {
random = arc4random_uniform(count);
[arr addObject:[NSNumber numberWithInteger:random]];
if(arr.count == count){
return arr;
}
}
}
將兩個數組分別使用選擇排序和插入排序進行排序,并計算耗時。
NSMutableArray * sortArray1 = createDifferentArr(10000);
NSMutableArray * sortArray2 = [sortArray1 mutableCopy];
NSInteger count = sortArray1.count;
//插入排序
double startTime1 = CFAbsoluteTimeGetCurrent();
for (int i = 1; i<count; i++) {
for (int j = i; j>0; j--) {
if (sortArray1[j] < sortArray1[j-1]) {
[sortArray1 exchangeObjectAtIndex:j withObjectAtIndex:j-1];
}else{
//提前結束,跳出循環
break;
}
}
}
double endTime1 = CFAbsoluteTimeGetCurrent();
NSLog(@"插入排序用時:%f s",endTime1 - startTime1);
//選擇排序
double startTime2 = CFAbsoluteTimeGetCurrent();
for (int i = 0; i< count; i++) {
int minIndex = i;
for (int j = i + 1; j < count; j++) {
if (sortArray2[j] < sortArray2[minIndex]) {
minIndex = j;
}
}
[sortArray2 exchangeObjectAtIndex:i withObjectAtIndex:minIndex];
}
double endTime2 = CFAbsoluteTimeGetCurrent();
NSLog(@"選擇排序用時:%f s",endTime2 - startTime2);
一萬數量級打印的結果為:
2017-07-10 18:31:53.407 插入排序用時:1.262208 s
2017-07-10 18:31:55.229 選擇排序用時:1.821002 s
2017-07-10 19:13:19.017 插入排序用時:1.281390 s
2017-07-10 19:13:20.891 選擇排序用時:1.872755 s
此時相差將近0.6秒。
而在兩萬的量級時,打印結果為:
2017-07-10 19:20:17.962 插入排序用時:5.300281 s
2017-07-10 19:20:25.706 選擇排序用時:7.742351 s
2017-07-10 19:20:49.626 插入排序用時:5.283061 s
2017-07-10 19:20:57.549 選擇排序用時:7.921418 s
此時相差了兩秒多。
- 而如果要排序的數組是近乎有序的數組時,差別將更加明顯。
我們修改下上面的生成隨機數組的函數。將隨機數范圍修改到0~1
random = arc4random_uniform(2);
此時在兩萬數量級下,打印結果為:
2017-07-10 20:38:45.100 插入排序用時:2.603737 s
2017-07-10 20:38:52.367 選擇排序用時:7.265069 s
2017-07-10 20:39:29.732 插入排序用時:2.630652 s
2017-07-10 20:39:37.727 選擇排序用時:7.993733 s