快速排序
快速排序的基本思想是:
- 選擇一個排序的切分點,對剩餘的部分進行從前至後的遍歷
- 從左邊開始向右,找到第一個比切分點大的值
- 從右邊開始向左,找到第一個比切分點小的值
- 交換兩個值的位置
- 這樣保證切分點左邊比切分點小,右邊比切分點小
- 同時交換的前提是兩個指針不發生碰撞(相遇) — 假定了切分點是在中間
- 這裏將第一個位置作爲切分點,因此還需要返回切分點的具體位置
- 在碰撞發生後,切分循環退出,這時需要交換低位(low)與碰撞的h
- 因爲發生碰撞時,h是不大於l的,需要交換兩個低位值,所以交換的是h和l(這裏有點不清楚)
- 在碰撞發生後,切分循環退出,這時需要交換低位(low)與碰撞的h
代碼實現:
public static void sort(int[] arr, int low, int high) {
if (low >= high) return;
int p = partition(arr, low, high);
// 對左半部分和右半部分切分,不包括切分點
sort(arr, low, p - 1);
sort(arr, p + 1, high);
}
private static int partition(int[] arr, int low, int high) {
int l = low, h = high + 1; // 取low可以不包括切分點
int v = arr[l]; // 切分點
while (true) {
// 找到較大值和較小值的位置,左半部分找較大值,右半部分找較大值,再進行交換
// 保證右邊的都是較大值,左邊的都是較小值
while (v > arr[++l] && l != high) ;
while (v < arr[--h] && h != low) ;
// 相遇則退出
if (l >= h) break;
// 不斷交換滿足條件的值
swap(arr, l, h);
}
// 此時指針相遇,交換低位,因爲是選擇低位作爲切分點
swap(arr, low, h);
return h;
}
// 用於交換的數組兩個位置的值
private static void swap(int[] arr, int a, int b) {
int temp = arr[a];
arr[a] = arr[b];
arr[b] = temp;
}