快排的基本思路:
1.需要双指针,分别是最左端和最右端的索引,之后需要找一个基准,一般都是选择第一个索引
2.把小于基准的数放到基准的左侧,大于基准的数放到基准的右侧。至此,一轮比较完成。
3.现在左右两侧相当于两个数组,分别对左右两侧的数组在各找一个基准,重复执行第2部,直到整体排序完成
详解:
首先最左端和最右端的索引分别记为 i=0 和 j=5
选择第一个索引值( i 0 =19 )作为基准,就相当于把最左侧的值赋值给基准(代码中的index),所以第一个索引的位置相当于一个坑, 现在需要填这个坑,所以需要右指针 j 从右向左开始依次找寻,直到找到比基准小的数来填这个坑。如下图, 索引4位置的数值15小于基准19,所以此时把15填入坑中。此时j=4 i需要加1 ,i=1
下图为原始数组
0 | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|
19 | 72 | 34 | 12 | 15 | 30 |
下图索引4位置15被填入坑中, 坑填上之后,索引4位置现在变成了一个新的坑。所以现在需要左指针 i 从左向右找寻比基准19大的数来填这个新的坑,于是索引1位置的72就填入了j=4 位置15的 新坑。填完之后 j需要减一 此时 i=1 j=3
0 | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|
15 | 72 | 34 | 12 | 15 | 30 |
下图索引1位置的72被填入新坑,现在索引1就成为了新的坑,于是右指针从右向左寻找比基准19小的数,于是索引3位置的12被填入新坑,i加1 ,此时 i=2 j=3
0 | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|
15 | 72 | 34 | 12 | 72 | 30 |
下图索引3位置的12被填入新坑,现在索引3位置的12成为了新的坑,于是左指针从左向右找寻比基准19大的数来填这个新的坑,于是索引2位置的34被填入新坑,j减1 此时i=2 j=2
0 | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|
15 | 12 | 34 | 12 | 72 | 30 |
下图索引2位置的34被填入新坑,于是索引2位置的34就成为了新坑,因为此时i=j=2,左右指针相等,说明第一轮结束,已经把小于基准的全部移到左边,大于基准的全部移到右边。所以此时基准19就会填入这个索引为2的坑
0 | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|
15 | 12 | 34 | 34 | 72 | 30 |
下图 基准19被填入索引为2的坑
0 | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|
15 | 12 | 19 | 34 | 72 | 30 |
现在只是基准的左侧都是比基准小,右侧都是比基准大。所以接下来我们要把基准两侧分别再去按照上面的步骤执行。
现在拿左侧举例:
同上面的步骤一样,i=0,j=1 基准=15
此时右指针从右向左找比基准小的数,显然索引1位置12比基准小。所以12被填入坑中,i加1 此时i=1,j=1
0 | 1 |
---|---|
15 | 12 |
下图12被填入坑中,所以此时索引1位置成为一个坑,因为i=j=1 所以次轮结束,所以需要将 基准填入索引1的坑。于是把15放入该坑
0 | 1 |
---|---|
12 | 12 |
如下图,15被填入新坑,至此,左侧就排好序了,右侧同理。所以整个数组排序完成
0 | 1 |
---|---|
12 | 15 |
下图java实现代码
public static void quickSort(int[] arr,int low,int upper){
if(low>=upper){
return;
}
int i=low;
int j=upper;
int index=arr[i];
while (i<j){
while (i<j && index<=arr[j]){//从右查询比index小的
j--;
}
if(i<j){
arr[i++]=arr[j];
}
while (i<j && index>arr[i]){//从左查询比index大的
i++;
}
if(i<j){
arr[j--]=arr[i];
}
}
arr[i]=index;
quickSort(arr,0,i-1);
quickSort(arr,i+1,upper);
}