快速排序
快速排序(Quick Sort) 的基本思想是:通過一趟排序將待排序的記錄分割成獨立的兩部分,其中一部分記錄的關鍵字均比另一部分記錄的關鍵字小,則可分別對這兩部分記錄繼續進行排序,以達到整個序列有序的目的。
動效圖如下:
快速排序動效圖
排序思路:
數組選第一個數,把比數小的放到數的左邊,比數大的放到右邊,結束后對左右兩邊的數組作重復處理即可。
排序演示:
假設數組為 [3,6,1,4,7,2,5]
下標 | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
---|---|---|---|---|---|---|---|
排序 | 3 | 6 | 1 | 4 | 7 | 2 | 5 |
以第一個元素3為基數,從最后一個元素開始查找比3小的數字,發現2,交換位置:
下標 | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
---|---|---|---|---|---|---|---|
排序 | 2 | 6 | 1 | 4 | 7 | 3 | 5 |
從2的右面開始與基數3比找比3大的數字,找到6,交換位置:
下標 | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
---|---|---|---|---|---|---|---|
排序 | 2 | 3 | 1 | 4 | 7 | 6 | 5 |
從6的左邊面開始與基數3比,找比3小的數字,找到1,交換位置:
下標 | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
---|---|---|---|---|---|---|---|
排序 | 2 | 1 | 3 | 4 | 7 | 6 | 5 |
結束第一次排序,分別開始對3的左右兩邊的數據作循環對比,左邊:2與1對比更改位置:
下標 | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
---|---|---|---|---|---|---|---|
排序 | 1 | 2 | 3 | 4 | 7 | 6 | 5 |
左邊結束。右邊:4為基數,從右邊開始找比4小的數,找不到,循環結束,因為4的左邊已經完畢,從4的右邊開始,也就是從7開始作基數對比,找比7小得數放到7的左面,找到5,交換位置:
下標 | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
---|---|---|---|---|---|---|---|
排序 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
從5的右邊查找發現已經有序,循環結束。
快速排序代碼:
- (void)quickSortArray:(NSMutableArray *)array withLeftIndex:(NSInteger)leftIndex andRightIndex:(NSInteger)rightIndex
{
if (leftIndex >= rightIndex) {//如果數組長度為0或1時返回
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開始往后找比基準數大的值 ***/
while (i < j && [array[i] integerValue] <= key) {//如果比基準數小,繼續查找
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];
}
NSMutableArray * arr = @[@16,@1,@2,@9,@7,@12,@5,@3,@8,@13,@10].mutableCopy;
[self quickSortArray:arr withLeftIndex:0 andRightIndex:arr.count-1];
打印結果為:
1, 2, 3, 5, 7, 8, 9, 10, 12, 13, 16
快速排序復雜度分析:
最優的情況下,時間復雜度為O(nlogn),最壞的情況下為O(n2)。平實的情況為O(nlogn)。
對于空間復雜度來說,主要是遞歸造成的棧空間的使用,最好情況,遞歸樹的深度為log?n,其空間復雜度也就是O(logn),最壞情況,需要進行n-1次遞歸調用,空間復雜度為O(n), 平均情況,空間復雜度為O(logn)
可惜的是,由于關鍵字的比較和交換是跳躍進行的,因此,快速排序是一種不穩定的排序方法。
上一篇:iOS算法總結-歸并排序
下一篇:iOS算法總結-回顧