快速排序原理
- 从待排序区间选择一个数,作为基准值(pivot);
- Partition: 遍历整个待排序区间,将比基准值小的(可以包含相等的)放到基准值的左边,将比基准值大的(可
以包含相等的)放到基准值的右边; - 采用分治思想,对左右两个小区间按照同样的方式处理,直到小区间的长度 == 1,代表已经有序,或者小区间
的长度 == 0,代表没有数据。
快速排序的实现
public class Sort {
public static void quickSort(int[] array) {
//辅助实现快速排序
quickSortHoare(array, 0, array.length - 1);
}
private static void quickSortHoare(int[] array, int left, int right) {
if (left >= right) {
return;
}
//得到一个基准值
int index = partition(array, left, right);
quickSortHoare(array, left, index - 1);
quickSortHoare(array, index + 1, right);
}
private static int partition(int[] array, int left, int right) {
int i = left;
int j = right;
int index = array[right];
while (i < j) {
while (i < j && array[i] <= index) {
i++;
}
while (i < j && array[j] >= index) {
j--;
}
swap(array, i, j);
}
swap(array, right, i);
return i;
}
private static void swap(int[] array, int x, int y) {
int temp = array[x];
array[x] = array[y];
array[y] = temp;
}
public static void main(String[] args) {
int[] arr = {9, 5 ,2 ,7 ,3, 8, 1, 4};
quickSort(arr);
System.out.println(Arrays.toString(arr));
}
}
时间复杂度 | 空间复杂度 |
---|---|
最坏 | 最坏 |
O(n^2) | O(n) |
稳定性:不稳定
非递归实现:
public static void quickSortByLoop(int[] array) {
Stack<Integer> stack = new Stack<>();
stack.push(array.length - 1);
stack.push(0);
while (!stack.isEmpty()) {
int left = stack.pop();
int right = stack.pop();
if (left >= right) {
continue;
}
int index = partition(array, left, right);
stack.push(right);
stack.push(index + 1);
stack.push(index - 1);
stack.push(left);
}
}
快速排序的优化:
1.选择基准值很重要,通常使用几组数取中值法
2.partition 过程中把和基准值相等的数也选择出来
3.待排序区间小于一个阈值时,使用其他排序