思想:
快速排序由冒泡改良而来,利用“分治”的思想,将原本的问题递归的分成两个子问题。在子问题里只剩下一个数字的时候,排序才算完成。
首先在序列中随机选择一个基准值(pivot),然后将除了基准值之外的数分为“比基准值小的数”和“比基准值大的数”两个子部分,然后对两个子部分同样进行分割,直到排序完成。
时间复杂度
平均:O(nlogn)
最差:O(n²)
基准值的选择
理论上讲是随机选择,在实际中,一般选择序列的第一个元素或者最后一个元素,一般以第一个元素居多。
代码实现
核心算法:
public class QuickSort {
public void sort(int[] arr,int liftIndex,int rightIndex){
if (liftIndex >= rightIndex){
return;
}
int pivotIndex = partition(arr,liftIndex,rightIndex);
sort(arr,liftIndex,pivotIndex - 1);
sort(arr,pivotIndex + 1,rightIndex);
}
private int partition(int[] arr,int liftIndex,int rightIndex) {
int pivot = liftIndex;
int temp;
while (liftIndex < rightIndex){
while (liftIndex < rightIndex && arr[rightIndex] > arr[pivot]){
--rightIndex;
}
while (liftIndex < rightIndex && arr[liftIndex] <= arr[pivot]){
++liftIndex;
}
//交换大小元素
if (liftIndex < rightIndex){
temp = arr[liftIndex];
arr[liftIndex] = arr[rightIndex];
arr[rightIndex] = temp;
}
}
//左右指针碰撞,将基准元素与左指针交换
if (liftIndex == rightIndex){
temp = arr[liftIndex];
arr[liftIndex] = arr[pivot];
arr[pivot] = temp;
//System.out.println("交换基准元素"+Arrays.toString(arr));
}
//返回左指针,用于下次的基准指针。
return liftIndex;
}
}
测试:
public class QuickTest {
public static void main(String[] args) {
int[] arr = new int[]{6,1,2,7,9,3,4,5,10,8};
System.out.println("排序前的数组"+ Arrays.toString(arr));
QuickSort quickSort = new QuickSort();
quickSort.sort(arr,0,arr.length-1);
System.out.println("排序后的数组"+ Arrays.toString(arr));
}
}
测试结果:
排序前的数组[6, 1, 2, 7, 9, 3, 4, 5, 10, 8]
排序后的数组[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
缺点
如果要实现序列的升序,而恰巧这个序列以降序排列,那么快速排序的作用也就失效了,退化成冒泡排序,时间复杂度也变为O(n²)。