挖坑填數+分治法:快速排序
版本 | 更新說明 | 時間 |
---|---|---|
1.0 | 新增本部落格 | 2020/10/18 |
1. 理論基礎
挖坑填數+分治法可以很形象的講述快速排序:
假設有如下陣列array
:
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
---|---|---|---|---|---|---|---|---|---|
72 | 6 | 57 | 88 | 60 | 42 | 83 | 73 | 48 | 85 |
現在我們要對它做升序排序
第一步,取基準數
理論上陣列的任一元素都可以作為基準數,這裡我們選擇第0號元素72,base = array[left]
現在陣列可以看成:
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
---|---|---|---|---|---|---|---|---|---|
6 | 57 | 88 | 60 | 42 | 83 | 73 | 48 | 85 | |
↑ left | ↑ right |
實際上0號位72仍然存在,但我們通過base將0號位的72儲存下來的,此時0號位上的元素可以被覆蓋,因此邏輯上我們抽象地將0號位看成空白,下面的論述仍然是如此
第二步:填坑
第一個坑已經出來,接下來我們就需要填這個坑:從右到左(←)找一個小於base的數
我們找到了
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
---|---|---|---|---|---|---|---|---|---|
6 | 57 | 88 | 60 | 42 | 83 | 73 | 48 | 85 | |
↑ left | ↑ right |
填進去
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
---|---|---|---|---|---|---|---|---|---|
48 | 6 | 57 | 88 | 60 | 42 | 83 | 73 | 85 | |
↑ left | ↑ right |
接下來從左向右(→)找到比base大的數,填充進去
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
---|---|---|---|---|---|---|---|---|---|
48 | 6 | 57 | 88 | 60 | 42 | 83 | 73 | 85 | |
↑ left | ↑ right |
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
---|---|---|---|---|---|---|---|---|---|
48 | 6 | 57 | 60 | 42 | 83 | 73 | 88 | 85 | |
↑ left | ↑ right |
依次類推,一個輪迴之後,就會變成如下陣列
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
---|---|---|---|---|---|---|---|---|---|
48 | 6 | 57 | 42 | 60 | 72 | 83 | 73 | 88 | 85 |
以base=72為基準,左邊的數都小於大,右邊的數都大於它,
接下來再對左右兩邊進行如此的快排,就能得到一個有序的陣列
2. 程式碼實現
public static void quickSort(int[] array, int left, int right){
if(left < right) {
int l = left, r = right;
int base = array[l];
while (l < r) {
// l小於r, 並且當前元素大於base,則繼續向前尋找
while (l < r && array[r] >= base) {
r--;
}
if (l < r) {
array[l] = array[r];
l++;
}
// l小於r, 並且當前元素小於base,則繼續向前尋找
while (l < r && array[l] <= base) {
l++;
}
if (l < r) {
array[r] = array[l];
r--;
}
}
array[l] = base;
quickSort(array, left, l - 1);
quickSort(array, r + 1, right);
}
}
3. 時間複雜度
最優情況:
O
(
l
o
g
2
n
)
O(log_2n)
O(log2n),每次都平分
最差情況:
O
(
n
2
)
O(n^2)
O(n2),每次都取到最大或最小,也就變成了氣泡排序
平均情況:
O
(
n
l
o
g
2
n
)
O(nlog_2n)
O(nlog2n)
相關文章
- 分治—快速排序排序
- 快速排序填坑口訣排序
- 分治思想--快速排序解決TopK問題排序TopK
- 如何避免前人挖坑,後人填坑
- 快速排序法排序
- 資料結構 8 基礎排序演算法詳解、快速排序的實現、瞭解分治法資料結構排序演算法
- 分治法
- 從零開始學資料結構和演算法 (五) 分治法 (二分查詢、快速排序、歸併排序)資料結構演算法排序
- 分治法求解問題
- 歸併排序(C++_分治遞迴)排序C++遞迴
- 分治法演算法學習(一)——歸併排序、求最大子陣列和演算法排序陣列
- 分治法求眾數和重數(含檔案輸入輸出)
- 挖坑
- PHP基礎演算法之快速排序法PHP演算法排序
- 排序之快速排序排序
- 排序:氣泡排序&快速排序排序
- 快速排序排序
- 快速排序&&歸併排序排序
- 快速排序快速入門排序
- alanwang[GDOU] 用選擇排序法對10個整數排序排序
- 排序演算法__快速排序排序演算法
- 排序演算法:快速排序排序演算法
- 選擇排序和快速排序排序
- 四、歸併排序 && 快速排序排序
- 排序演算法 - 快速排序排序演算法
- javascript 快速排序JavaScript排序
- 快速排序javaScript排序JavaScript
- js 快速排序JS排序
- 快速排序-java排序Java
- LeetCode:快速排序LeetCode排序
- java 快速排序Java排序
- python 快速排序Python排序
- php插入排序,快速排序,歸併排序,堆排序PHP排序
- 排序演算法之 '快速排序'排序演算法
- 【LeetCode】【分治法】連續數列(最大子序和)思路解析和程式碼LeetCode
- LeetCode169求眾數——分治LeetCode
- 遞迴-*快速排序遞迴排序
- 快速排序 (Quick Sort)排序UI