快速排序算法思想
快速排序和歸并排序是互補的,歸并排序將整個數組分成小數組,然后將排好序的小數組歸并以將整個數組排序;而快速排序是在將大數組分成小數組的時候排序,當小數組小到不可再分的時候,排序也就完成了。
1.首先選擇一個中間元素(一般選左端或者右端)。
2.分別獲取除中間元素外的左右兩端的索引。
3.由左右兩端逐漸向中間迭代,每迭代一步比較一下索引中的元素和中間元素,當左邊出現比中間元素大的元素的時候,暫停左邊的迭代,當右邊迭代出比中間元素小的元素的時候,右邊迭代也暫停,交換左右兩邊的元素。
4.重復步驟3,直到左右兩邊的索引相遇,然后將中間元素移動到中間,這時中間元素左邊的元素都比它小,右邊的元素都比它大。
5.將上面的中間元素左右兩邊當成兩個數組,分別進行上述過程。
6.重復以上步驟直到數組不可再分。
快速排序算法實現
public static void main(String[] args) {
int[] arr = {-2, 1, 33, 4, 5, 0, 0, -1, 45, 908, 3};
int low = 0;
int high = arr.length - 1;
quickSort(arr, low, high);
for (int i : arr) {
System.out.print(i + " ");
}
}
/**
* 快速排序
* @param arr
* @param low
* @param high
*/
private static void quickSort(int[] arr, int low, int high) {
if (low >= high) return;
// 分成兩個
int p1 = getPartion(arr, low, high);
int p = getPartionOne(arr, low, high);
System.out.println(p1 == p);
quickSort(arr, low, p - 1);
quickSort(arr, p + 1, high);
}
/**
* 切分
* @param arr
* @param left
* @param right
* @return
*/
private static int getPartionOne(int[] arr, int left, int right) {
int tmp = arr[left];
int i = left;
int j = right + 1;
while (true) {
while (arr[++i] < tmp) {
}
while (arr[--j] > tmp) {
}
if (i >= j) {
break;
}
exchage(arr, i, j);
}
exchage(arr, left, j);
return left;
}
/**
* 交換
* @param arr
* @param i
* @param j
*/
private static void exchage(int[] arr, int i, int j) {
int aux = arr[i];
arr[i] = arr[j];
arr[j] = aux;
}
/**
* 總感覺這個切分更好理解
* @param arr
* @param left
* @param right
* @return
*/
private static int getPartion(int[] arr, int left, int right) {
int tmp = arr[left];
while (left < right) {
while (left < right && arr[right] > tmp)
right--;
arr[left] = arr[right];
while (left < right && arr[left] <= tmp)
left++;
arr[right] = arr[left];
}
arr[left] = tmp;
return left;
}
算法復雜度
1.平均時間復雜度: O(NLogN)
2.最好情況時間復雜度: O(NLogN)
3.最差情況時間復雜度: O(NLogN)
4.所需要額外空間: O(1)
算法穩定性
- 快速排序是不穩定的
想看完整版請點擊:快速排序