快速排序算法
快速排序是一种分治的排序算法,和冒泡排序同属于交换排序。
快速排序在每一轮都挑选一个基准元素,并让比它小的元素移到数列的一边,比它大的元素移到数列数列的另一边,从而把数列拆分成两部分。
排序流程
- 从数列中挑出一个基准元素(pivot);
- 所有比基准值小的元素移动到基准前面,其它比基准值大的元素移到基准的后面(相同的数可以不动)。完成后该基准就处于数列的中间位置,称为分区操作;
- 递归地把小于基准值元素的子数列和大于基准值元素的子数列排序。
动图
算法分析
快速排序算法的效率在序列越乱的时候,效率越高,在数据有序时,会退化成冒泡排序。
优点:极快数据移动少。
缺点:不稳定。
最佳情况:O(nlogn)
最差情况:O(n^2)
平均情况:O(nlogn)
空间复杂度:O(nlogn)
java代码
@Override
public <T extends Comparable<T>> T[] sort(T[] array) {
doSort(array, 0, array.length - 1);
return array;
}
private static <T extends Comparable<T>> void doSort(T[] array, int left, int right) {
if (left < right) {
int pivot = randomPartition(array, left, right);
doSort(array, left, pivot - 1);
doSort(array, pivot, right);
}
}
private static <T extends Comparable<T>> int randomPartition(T[] array, int left, int right) {
int randomIndex = left + (int)(Math.random()*(right - left + 1));
swap(array, randomIndex, right);
return partition(array, left, right);
}
private static <T extends Comparable<T>> int partition(T[] array, int left, int right) {
int mid = (left + right) / 2;
T pivot = array[mid];
while (left <= right) {
while (less(array[left], pivot)) {
++left;
}
while (less(pivot, array[right])) {
--right;
}
if (left <= right) {
swap(array, left, right);
++left;
--right;
}
}
return left;
}