1、概述
快速排序怎么排序的?为什么叫做快速排序?速度快?
快速排序采用分治的思想,通过一趟快速排序将待排序列分为两个部分,其中的一部分记录比关键字小的元素,另一部分记录比关键字大的元素,知道达到整个序列有序的目的。
具体思想:
① 在待排序序列中取出一个元素作为基准,称为基准记录
② 定义两个索引left和right,分别表示 首索引和尾索引,key为基准值
③ 首先,尾索引向前扫描,找到比基准值小的记录,并替代首索引对应的值
④ 然后,尾索引向后扫描,直到找到比基准值大的记录,斌替换尾索引对应的值
⑤ 在扫描过程中首索引等于尾索引(left = right),则一趟排序结束;将基准值(key)替换首索引所对应的值
⑥ 进行下一趟排序时,待排序列被分成两个区:[0,left-1],[righ+1,end]
⑦ 重复以上步骤,直至排序完成
图形演示:
2、代码演示
/*
* 快速排序:找一个基准元素,
* 两个索引:尾索引指向的序列的最后一个元素,首索引指向的是第一个元素
* 尾索引向前扫描,直到找到比基准元素小的元素,放到首索引的位置
* 首索引向后扫描,直到找到比基准元素大的元素,放到尾索引的位置
* 在扫描过程中,当left=right(首索引和尾索引相遇的时候),则一趟排序结束,将基准值key替换首索引所对应的位置
* 进行下一趟排序,待排成的序列分为:[0,left-1],[right + 1, end]
* 重复以上操作
*/
// 快速排序是 从往两边排序 中间的序列是有序的
public class QuickSort {
public static void main(String[] args) {
int[] arr = {21,12,31,1,3,53,9};
quickSort(arr, 0, 6);
for(int i = 0;i < arr.length;i++) {
System.out.print(arr[i] + " ");
}
}
private static void quickSort(int[] array,int leftIndex,int rightIndex) {
// 判断是否首索引比尾索引大
if(leftIndex >= rightIndex) {
return;
}
//设置基准元素和首尾索引
int left = leftIndex;
int right = rightIndex;
int key = array[left];
// 当符合条件的时候
while(left < right) {
// 从右往左 尾索引向左扫描 找比基准元素小的
while(left < right && array[right] >= key) {
// 符合条件的话就往前走
right--;
}
// 当条件结束的时候 把符合条件的元素 找比基准元素大的
array[left] = array[right];
while(left < right && array[left] <= key) {
left++;
}
// 找到这种元素然后放到后面
array[right] = array[left];
// 当left == right的时候,基准位置赋值
array[left] = key;
}
// 对基准位左边的位置递归排序
quickSort(array,leftIndex,left-1);
// 对基准位右边的位置递归排序
quickSort(array,right + 1,rightIndex);
}
}
3、算法复杂度分析
快速排序之所比较快,因为相比冒泡排序,每次交换是跳跃式的。每次排序的时候设置一个基准点,将小于等于基准点的数全部放到基准点的左边,将大于等于基准点的数全部放到基准点的右边。这样在每次交换的时候就不会像冒泡排序一样每次只能在相邻的数之间进行交换,交换的距离就大的多了。因此总的比较和交换次数就少了,速度自然就提高了。当然在最坏的情况下,仍可能是相邻的两个数进行了交换。因此快速排序的最差时间复杂度和冒泡排序是一样的都是O(N2),它的平均时间复杂度为O(NlogN)。