排序算法采用了一种分治的策略,即将大模块划分成同样的小模块。
快排的基本思想:
- 先从数组中取出一个数作为基准数,通常取数组的第一个元素作为基准数
- 分区过程,将比基准数大的数放到他的右边,小于或等于他的数放到左边
- 经过一次分区后,便可以将原数组分成基准数的左边都小于等于基准数,而右边都大于基准数的数组。重复第2步的过程,直到区间只有一个数,最终就可以得到一个有序的数组
快速排序实际上就是挖坑+填数+分治的过程。
以一个数组arr为例,取第一个数作为基准数
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
72 |
6 |
55 |
80 |
60 |
90 |
42 |
73 |
48 |
100 |
初始时 i=0,j=5,x=arr[0]。
由于已经将arr[0]保存到x了,所以arr[0]可以被其他数填充了,相当于在arr[0]上挖了个坑。
j从右向左遍历数组,找第一个小于等于x的数,在j=8的位置满足要求,将arr[8]挖出填到arr[0]中,同时i++,此时arr[8]多出一个坑位,等待其他数填充。i从左向右遍历,找到第一个比x大的数,i=3符合要求,将arr[3]的数取出填到arr[8]中,同时j--,数组变为
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
48 |
6 |
55 |
80 |
60 |
90 |
42 |
73 |
80 |
100 |
此时i=3,j=7,x=72;
再重复上面的步骤,先从后向前找,再从前向后找。
从j开始向前找,j=6,符合条件,arr[6]挖出一个坑填到arr[3]上,arr[3]=arr[6];i++
从i开始向后找,i=5,符合条件,arr[5]挖坑填到arr[6]上,arr[6]=arr[5];j--;
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
48 |
6 |
55 |
42 |
60 |
90 |
90 |
73 |
80 |
100 |
此时i==j=5,将arr[5]用x填上,即arr[5]=x;
数组变为:
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
48 |
6 |
55 |
42 |
60 |
72 |
90 |
73 |
80 |
100 |
可以看出arr[5]左边的数都小于等于arr[5],arr[5]右边的数都大于他
对arr[5]左边和右边的两个子数组递归实现上述过程,最终可以得到一个有序的数组。
对挖坑填数进行总结:
- i=L,j=R,将基准数挖出,形成第一个坑arr[i]
- 由后向前找第一个小于等于基准数的数arr[j],找到后挖出此数形成第二个坑arr[j],arr[i]=arr[j];
- 由前向后找第一个大于基准数的数arr[i],找到后挖出此数形成新坑arr[i],arr[j]=arr[i];
- 重复执行第2、3步,直到i==j,填坑arr[i]=基准数
- 分别对arr[i]的左右两边递归调用,从而达到数组有序的目的
代码实现如下:
package com.atguigu.sort;
import java.util.Arrays;
public class QuickSort {
public static void main(String[] args) {
int[] arr= {72,6,55,80,60,90,42,73,48,100};
quickSort(arr, 0, arr.length-1);
System.out.println(Arrays.toString(arr));
}
public static void quickSort(int[] arr,int low,int high) {
int X=arr[low];//挖坑
int i=low;
int j=high;
if(low<high) {//递归结束的条件
while(i<j) {
while(i<j&&arr[j]>X) {//从右向左找小于于等于X的数
j--;
}
if(i<j) {
arr[i++]=arr[j];//arr[i]处填坑,arr[j]形成了新坑
}
while(i<j&&arr[i]<=X) {//从左向右找大于X的数
i++;
}
if(i<j) {
arr[j++]=arr[i];//arr[j]处填坑,arr[i]形成了新坑
}
}
//i==j处结束循环
arr[i]=X;//arr[i]处填坑
//分治
quickSort(arr, low, i-1);//在arr[i]的左边递归调用
quickSort(arr, i+1, high);//在arr[i]的右边递归调用
}
}
}
来源:CSDN
作者:我就是个渴望成长的小菜鸡
链接:https://blog.csdn.net/junjunjiao0911/article/details/103916248