什么是“快速排序”。
对于待排序的数组,我们选取一个数值作为基础值(通常为 数组第一个值),将数组分为两部分,前面的一部分:数值都小于基础值,后面的数值都大于基础值。然后继续对分开的数组进行同样的操作,递归。
为什么 “快速”。
由于已经分成了两部分,这样就不需要进行比较了,减少了时间。
算法详述
对于给定数组 “6 1 2 7 9 3 4 5 10 8”。
- 选取基础值(6)
- 设置两个索引(i,j)
- j从后向前 逼近,寻找一个比基础值 小 的数值
- i从前向后逼近,找一个比基础值大的数值。
ps: 一定是后面 j 先移动。当j 找到之后,i 才开始移动寻找。当两者找到都找到之后,交换两者的数值。
例子:
开始状态:
i | j | ||||||||
6 | 1 | 2 | 7 | 9 | 3 | 4 | 5 | 10 | 8 |
begin: i 寻找一个比6大的数值,j 找一个比6小的数值。
i | j | ||||||||
6 | 1 | 2 | 7 | 9 | 3 | 4 | 5 | 10 | 8 |
找到了 | 找到了 |
找到之后,交换两者数值
i | j | |||||||||
6 | 1 | 2 | 5 | 9 | 3 | 4 | 7 | 10 | 8 | |
继续寻找:j 继续寻找一个比6小的数值, i 寻找一个比6大的数值。
i | j | |||||||||
6 | 1 | 2 | 5 | 9 | 3 | 4 | 7 | 10 | 8 | |
找到了 | 找到了 |
j 找到之后(4<6),i 才开始寻找比6大的数值。
交换两者数值。
i | j | |||||||||
6 | 1 | 2 | 5 | 4 | 3 | 9 | 7 | 10 | 8 | |
继续寻找。
j 首先移动,此时 j 移动到3位置,3<6 ; 那么 , i 开始移动,但是! 此时 i 移动到3 位置,两者 i==j了,那么 就只交换 3和6的值。
i | j | |||||||||
6 | 1 | 2 | 5 | 4 | 3 | 9 | 7 | 10 | 8 | |
如下:
i | j | |||||||||
3 | 1 | 2 | 5 | 4 | 6 | 9 | 7 | 10 | 8 | |
至此,我们已经找了两部分,
- 第一部分为 “3 1 2 5 4”
- 第二部分为“9 7 10 8 ”
那么剩下的,就可以使用递归实现啦。
public static void quickSort(int[] arr,int low,int high){
int i,j,temp,t;
if(low>high){
return;
}
i=low;
j=high;
//temp就是基准位
temp = arr[low];
while (i<j) {
//先看右边,依次往左递减
while (temp<=arr[j]&&i<j) {
j--;
}
//再看左边,依次往右递增
while (temp>=arr[i]&&i<j) {
i++;
}
//如果满足条件则交换
if (i<j) {
t = arr[j];
arr[j] = arr[i];
arr[i] = t;
}
}
//最后将基准为与i和j相等位置的数字交换
arr[low] = arr[i];
arr[i] = temp;
//递归调用左半数组
quickSort(arr, low, j-1);
//递归调用右半数组
quickSort(arr, j+1, high);
}
以上都是个人根据以下两位作者的文章,理解到了。
第一位:https://blog.csdn.net/shujuelin/article/details/82423852 感谢作者辛苦劳动
第二位:https://www.cnblogs.com/surgewong/p/3381438.html 同样感谢作者辛苦劳动
谢谢两位作者,本人写的肯定会有问题,多多指教。