题目
对于数组使用快速排序算法进行排序
输入
[6,1,2,7,9,3,4,5,10,8]
输出
[1,2,3,4,5,6,7,8,9,10]
解析
假设我们现在对数据arr[6,1,2,7,9,3,4,5,10,8]这个10个数进行排序。
首先在这个序列中随便找一个数作为基准数。选取第一个数6作为基准数。在这个序列中,将所有比基准数大的数放在6的右边,比基准数小的数放在6的左边,类似下面这种排列:[3,1,2,5,4,6,9,7,10,8]
在初始状态下,数字6在序列的第1位。我们的目标是将6挪到序列中间的某个位置,假设这个位置是k。现在就需要寻找这个k,并且以第k位为分界点,左边的数都小于等于6,右边的数都大于等于6。
具体步骤如下
-
使用指针i,j分别从左向右找大于6的数、从右向左找小于6的数。注意每次都是j先移动,找到满足条件的数后再移动i
-
查找到符合条件的数arr[3],arr[7],交换二者
-
继续移动i,j找到第二组满足条件的数,并交换二者
-
继续移动i,j,先移动j,j=5,arr[j]=3,再移动i,i右移后与j重叠,终止移动。由于j先移动,此时停止有两种情况要么j移动到i要么j找到了小于基准数6的值,所以终止后将arr[j]与基准数交换
-
至此第一轮探测结束,得到以6为基准数、左侧均小于6右侧均大于6的数组。以6为分界点,对6两边数组重复执行上述操作,直至排序出所有数据
-
得到最终排序结果
编码
public static void main(String[] args) {
int[] arr = {6,1,2,7,9,3,4,5,10,8};
print("输入",arr);
quickSort(arr,0,arr.length-1);
print("输出",arr);
}
private static void quickSort(int[] arr, int left, int right) {
// 起始大于终止时结束
if(left>right){
return;
}
int i = left;
int j = right;
int base = arr[left];
while(i<j){
// 右指针向左查找大于等于基准数的值
while(i<j && arr[j] >= base){
j--;
}
// 左指针向右查找小于等于基准数的值
while(i<j && arr[i]<=base){
i++;
}
// 如果左指针小于右指针,执行交换
if(i<j){
swap(arr,i,j,base);
}
}
// 由于每次都是右指针先移动,那么上面循环终止条件要么j找到了小于等于基准数的值要么j=i,此时arr[j]一定小于等于基准数,执行交换
if(left<i){
swap(arr,left,i,base);
}
// 递归执行基准数左侧数组
quickSort(arr,left,j-1);
// 递归执行基准数右侧数组
quickSort(arr,j+1,right);
}
private static void swap(int[] arr,int i,int j,int base){
System.out.println("");
print("执行交换[base="+base+",i="+i+",j="+j+"]");
print("交换前",arr);
int temp = arr[i];
arr[i]=arr[j];
arr[j]=temp;
print("交换后",arr);
}
运行结果
执行交换[base=6,i=3,j=7]
交换前:[6,1,2,7,9,3,4,5,10,8]
交换后:[6,1,2,5,9,3,4,7,10,8]
执行交换[base=6,i=4,j=6]
交换前:[6,1,2,5,9,3,4,7,10,8]
交换后:[6,1,2,5,4,3,9,7,10,8]
执行交换[base=6,i=0,j=5]
交换前:[6,1,2,5,4,3,9,7,10,8]
交换后:[3,1,2,5,4,6,9,7,10,8]
执行交换[base=3,i=0,j=2]
交换前:[3,1,2,5,4,6,9,7,10,8]
交换后:[2,1,3,5,4,6,9,7,10,8]
执行交换[base=2,i=0,j=1]
交换前:[2,1,3,5,4,6,9,7,10,8]
交换后:[1,2,3,5,4,6,9,7,10,8]
执行交换[base=5,i=3,j=4]
交换前:[1,2,3,5,4,6,9,7,10,8]
交换后:[1,2,3,4,5,6,9,7,10,8]
执行交换[base=9,i=8,j=9]
交换前:[1,2,3,4,5,6,9,7,10,8]
交换后:[1,2,3,4,5,6,9,7,8,10]
执行交换[base=9,i=6,j=8]
交换前:[1,2,3,4,5,6,9,7,8,10]
交换后:[1,2,3,4,5,6,8,7,9,10]
执行交换[base=8,i=6,j=7]
交换前:[1,2,3,4,5,6,8,7,9,10]
交换后:[1,2,3,4,5,6,7,8,9,10]
输出:[1,2,3,4,5,6,7,8,9,10]