算法思想
- 如果要排序數組中下標從 p 到 r 之間的一組數據,我們選擇 p 到 r 之間的任意一個數據作爲 pivot(分區點)。我們遍歷 p 到 r 之間的數據,將小於 pivot 的放到左邊,將大於 pivot 的放到右邊,將 pivot 放到中間。經過這一步驟之後,數組 p 到 r 之間的數據就被分成了三個部分,前面 p 到 q-1 之間都是小於 pivot 的,中間是 pivot,後面的 q+1 到 r 之間是大於 pivot 的。根據分治、遞歸的處理思想,我們可以用遞歸排序下標從 p 到 q-1 之間的數據和下標從 q+1 到 r 之間的數據,直到區間縮小爲 1,就說明所有的數據都有序了。
代碼實現
public void partition(int[] list, int startIdx, int endIdx) {
if(startIdx == endIdx - 1) {
if(sortType == SortType.Positive.type() ? list[startIdx] > list[endIdx] : list[startIdx] < list[endIdx]) {
int tmp = list[startIdx];
list[startIdx] = list[endIdx];
list[endIdx] = tmp;
}
return;
}
int flag = startIdx;
int pivot = list[endIdx];
for(int k = startIdx; k < endIdx ; k++) {
if(sortType == SortType.Positive.type() ? list[k] < pivot : list[k] > pivot) {
int tmp = list[flag];
list[flag] = list[k];
list[k] = tmp;
flag++;
}
}
// 如果遊標不是最後一位,遊標位置和最後的標誌位互換
if(flag < endIdx) {
int tmp = list[flag];
list[flag] = list[endIdx];
list[endIdx] = tmp;
}
// 處理小的區間
// 如果小區間的元素大於1個
if(startIdx + 1 < flag) {
partition(list, startIdx, flag - 1);
}
// 處理大的區間
// 如果大區間一個元素都沒有了
if(flag + 1 < endIdx) {
partition(list, flag + 1, endIdx);
}
}
@Override
public void testSort(int[] list) {
partition(list, 0, list.length - 1);
}
完整代碼見:快速排序