概述:
快速排序(Quicksort)是实践中最常用的排序算法之一。与归并排序一样,快速排序也是一种分治的递归算法。
快排的前身是归并,而正是因为归并存在不可忽视的缺点,才产生了快排。归并的最大问题是需要额外的存储空间,并且由于合并过程不确定,致使每个元素在序列中的最终位置上不可预知的。针对这一点,快速排序提出了新的思路:把更多的时间用在“分”上,而把较少的时间用在“治”上。从而解决了额外存储空间的问题,并提升了算法效率。
何谓分治思想?
所谓的分治思想就是对一个问题“分而治之”,用分治思想来解决问题需要两个步骤:
- 如何将一个问题分成两个子问题?
- 如何解决分成的这两个子问题?
快排步骤:
- 首先选择待排序的列表中的其中一个数字,作为基准数(pivot),所谓基准数,其实就是一个参考数;一般选择第一个数作为基准数。
- 然后从最后一个数开始从后往前检索,寻找比基准数小的数,若找到则指针停下,再从前往后检索,寻找比基准数大的数,若找到则让小的数和大的数交换位置。(总之就是把小于基准数的所有数字放到这个数的左边,大于这个数的所有数字放到基准数的右边。)
- 此时第一轮排序完成,然后使用递归继续检索,直到排序完成。
代码如下:
public static void main(String[] args) {
int[] arr = {6,3,7,9,8,5,1,4,8};
quickSort(arr,0,arr.length-1);
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i]+" ");
}
}
//快速排序
public static void quickSort(int[] arr,int left,int right){
//进行判断,如果左边索引比右边索引要大,是不合法的,直接return
if (left>right){
return;
}
//定义变量保存基准数
int pivot = arr[left];
//定义变量i,指向左边
int i = left;
//定义变量j,指向右边
int j = right;
//当i和j不相遇的时候,在循环中检索
while (i!=j){
//先由j从右往左检索,检索到比基准数小的就停下
//如果检索到比基准数大的或者相等的,就继续检索
while (arr[j] >= pivot && i<j){
j--; //从右往左移动
}
//i从左往右检索
while (arr[i] <= pivot && i<j){
i++; //i从左往右移动
}
//代码走到这里,i停下了,j也停下了,然后交换i和j的元素
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
//如果上面while循环条件不成立,说明i和j相遇
//那么就交换基准数和相遇位置的元素。
//把相遇位置的元素值赋给基准数这个位置的元素
arr[left] = arr[i];
//把基准数位置的元素值赋给相遇位置的元素
arr[i] = pivot;
//基准数在这里就归位了,左边的数比它小,右边的数比它大
//排基准数的左边
quickSort(arr,left,i-1);
//排基准数的右边
quickSort(arr,j+1,right);
}
控制台输出结果:
1 3 4 5 6 7 8 8 9
若有问题,欢迎指正!