標籤:要求 第一步 並且 個數 利用 oid 結果 有序 序列
一.快速排序概念及其思想
快速排序(QuickSort),又稱為交換排序,是分治演算法的一種,快速排序採用分治的策略。
1.分治法的基本思想:
將原問題分解為若干個規模更小但結構和原問題相似的子問題。遞迴這些子問題,然後將這些子問題的解組合為原問題的解。
2.快速排序的基本思想
通過一趟排序將要排序的資料分割成獨立的兩部分,其中一部分的所有資料都比另外一部分的所有資料都要小,然後再按此方法對這兩部分資料分別進行快速排序,整個排序過程可以遞迴進行,以此達到整個資料變成有序序列。
二.快速排序步奏解釋
設當前待排序的無序區為R[low..high],利用分治法可將快速排序的基本思想描述為:
①分解:
在R[low..high]中任選一個記錄作為基準(Pivot),以此基準將當前無序區劃分為左、右兩個較小的子區間R[low..pivotpos-1)和R[pivotpos+1..high],並使左邊子區間中所有記錄的關鍵字均小於等於基準記錄(不妨記為pivot)的關鍵字pivot.key,右邊的子區間中所有記錄的關鍵字均大於等於pivot.key,而基準記錄pivot則位於正確的位置(pivotpos)上,它無須參加後續的排序。
注意:
劃分的關鍵是要求出基準記錄所在的位置pivotpos。劃分的結果可以簡單地表示為(注意pivot=R[pivotpos]):
R[low..pivotpos-1].keys≤R[pivotpos].key≤R[pivotpos+1..high].keys
其中low≤pivotpos≤high。
②求解:
通過遞迴調用快速排序對左、右子區間R[low..pivotpos-1]和R[pivotpos+1..high]快速排序。
③組合:
因為當"求解"步驟中的兩個遞迴調用結束時,其左、右兩個子區間已有序。對快速排序而言,"組合"步驟無須做什麼,可看作是空操作。
簡單地說:
步奏詳解
1 ).設定兩個變數i,j ,排序開始時i = 0,就j = mutableArray.count - 1;
2 ).設定數組的第一個值為比較基準數key,key = mutableArray.count[0];
3 ).因為設定key為數組的第一個值,所以先從數組最右邊開始往前尋找比key小的值。如果沒有找到,j--繼續往前搜尋;如果找到則將mutableArray[i]和mutableArray[j]互換,並且停止往前搜尋,進入第4步;
4 ).從i位置開始往後搜尋比可以大的值,如果沒有找到,i++繼續往後搜尋;如果找到則將mutableArray[i]和mutableArray[j]互換,並且停止往後搜尋;
5 ).重複第3、4步,直到i == j(此時剛好執行完第三步或第四部),停止排序;
假設mutableArray = [@(4),@(3),@(7),@(1),@(5),@(8)]
下標 |
0 |
1 |
2 |
3 |
4 |
5 |
資料 |
4 |
3 |
7 |
1 |
5 |
8 |
第一步:i = 0; j = 5; key = 4;
第二步:要找比key小的指,從右往前找,j不斷遞減,直到找到第一個比key小的,然後將mutableArray[i]和mutableArray[j]互換
下標 |
0 |
1 |
2 |
3 |
4 |
5 |
資料 |
1 |
3 |
7 |
4 |
5 |
8 |
i = 0; j = 3; key = 4;
第三步:要找比key大的指,從左往後找,i不斷遞增,直到找到第一個比key大的,然後將mutableArray[i]和mutableArray[j]互換
下標 |
0 |
1 |
2 |
3 |
4 |
5 |
資料 |
1 |
3 |
4 |
7 |
5 |
8 |
i = 2; j = 3; key = 4;
接著j--,則i==j;這樣就稱為一次迴圈
然後將key左邊,右邊的值分別當做一個數組重複上面步驟
三.任何的說法都是……,上代碼
#import "ViewController.h"@interface ViewController ()@end@implementation ViewController- (void)viewDidLoad { [super viewDidLoad]; NSMutableArray *arr = [[NSMutableArray alloc]initWithObjects:@(100), @(1),@(8),@(5),@(9),@(4),@(3),@(7),nil]; [self quickSortArray:arr withLeftIndex:0 andRightIndex:arr.count -1]; NSLog(@"%@",arr); }- (void)quickSortArray:(NSMutableArray *)array withLeftIndex:(NSInteger)leftIndex andRightIndex:(NSInteger)rightIndex{ if (leftIndex >= rightIndex) { return; } NSInteger i = leftIndex; NSInteger j = rightIndex; //基準數 NSInteger key = [array[i]integerValue]; while (i < j) { /**** 首先從右邊j開始尋找比基準數小的值 ***/ while (i < j && [array[j]integerValue] > key) { j--; } //如果比基數小,則將尋找到的小值重新調換到i的位置 array[i] = array[j]; /**當在右邊尋找到一個比基準數小的值時,就從i開始往後找就從i開始往後找比基數大的值*/ while (i < j && [array[i]integerValue]) { i++; } //如果比基準數大,則將尋找到的大值調換到j的位置 array[j] = array[i]; } array[i] = @(key); //排序基準數左邊的 [self quickSortArray:array withLeftIndex:leftIndex andRightIndex:i - 1]; //排序基準數右邊的 [self quickSortArray:array withLeftIndex:i + 1 andRightIndex:rightIndex];}
時間複雜度:
其實對快排而言,最好的情況就是每次partition操作的元素正好插在整個子序列的中間,這樣是最好的,因此最好效率是N*logN。最壞情況當然就是往兩極插了,N方。
iOS 快速排序