![在这里插入图片描述](https://img-blog.csdnimg.cn/265326a5e4ed4796aefc779eef2806c4.webp#pic_center)
一.简述快速排序
所谓快速排序,其最大特点就是快,如何能快?当然是时间复杂度与空间复杂度均较小,就会快了。快速排序是一种基于分而治之思想的的排序算法,说到分而治之,是不是很容易想到二分法?它的时间复杂度是log(n),那我们可不可以将一个数组不断进行诸如二分法般的排序?
二.具体讲述
1.基准值
下面我们就来讲一讲具体的思想,首先我们拿到了一个数组,以{5,4,3,9,8,2,3,4,5,8,10}为例,我们需要选定一个标准值,所谓的标准值就是我们要以他为中轴将数列按大小一分为二的元,目的在于完成第一次的“二分”,这里我们将最左边的数记为基准值。
2.数组的第一次变化
那接下来该如何完成第一次二分呢?我们前后各选定一个标记,分别记为i与j。i的使命在于找出比基准值大的数,让比基准值小的数留在左边,j的使命在于找到比基准值小的数,让大的数留在右边。
因为此处设置的基准数是最左边的数,所以需要让j先向右移,这一点非常重要,为何j先移动?大家先思考一下,我后面补充。
j向左移动,目的在于找出比基准值即6小的数,当遇到比5小的数4便停下来,然后i开始向右移动目的在于找到比基准值6大的数,遇到9停下来,然后4和9交换位置,那么此时在i的左边都是比基准值小的数,在j的右边都是比基准值大的数。
3.数组第一轮变化
参照数组的第一次,如此继续,4和8交换,然后j继续左移遇到3停下,然后i开始右移去寻找比基准值大的数,但i<j是我们的前提条件,此时i与j在4处相遇,此时4与5(基准值)交换,完成第一轮.第一轮变化便是核心,接下来便是重复上述操作。
三.具体代码实现
public class QuickSort {
/*int[] arr;
int low;
int high;*/
public static void QuickSortMini(int[] arr, int low, int high) {
int i, j, temp,t;
/*旨在最后就剩一个元素了,此时其内的i == j,下一步进行递归时,出现low>high跳出方法,不然就是死循环
//将左侧的数据进行递归
QuickSortMini(arr,low,j-1);
//对右边的数据进行递归
QuickSortMini(arr,j+1,high);*/
if(low>high){
return;
}
i = low;
j = high;
temp = arr[low];
while (i < j) {
//从右边开始看
while (arr[j] >= arr[low] && j > i){
j--;
}
//从左边看
while (arr[i] <= arr[low] && i < j){
i++;
}
if (arr[j] < temp && arr[i] > temp){
t = arr[j];
arr[j] = arr[i];
arr[i] = t;
}
}
//最后将基准值与arr[i]交换
arr[low] = arr[i];
arr[i] = temp;
//将左侧的数据进行递归
//在第二次及以后,较于第一次基准值右边的第二次递归后左边的数组
// 这里的low就是上一次递归结束后的j+1
QuickSortMini(arr,low,j-1);
//对右边的数据进行递归
//在第二次及以后,较于第一次基准值左边边的第二次递归后右边的数组
// 这里的low就是上一次递归结束后的j-1
QuickSortMini(arr,j+1,high);
}
public static void main(String[] args) {
int[] arr = new int[]{8,1,2,3,4,5,6,99,88};
//遍历输出
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i]+"\t");
}
System.out.println();
//调用函数进行排序
QuickSortMini(arr,0,arr.length-1);
//遍历输出
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i]+"\t");
}
}
}
四.补充
为何j先移动?
在前面我抛出一个问题让大家思考,下面来说一下我的看法:
j先移动,最主要的原因在于基准值是选在最左边的。j先移动确保了在j停下来处的值是大于基准值的或者是与i共同停在了比基准值小的数上,因为他停下来的条件要么是找到了比基准值小的数,要么就是和i相遇了,而是j先动,i再动,i比基准值5小的数上或者是与j共同停在了比基准值小的数上,故保证了最后和基准值交换时的数是小于基准值的,即保证了基准值的左边小于他,大于他的数在右边。
五.写在最后题
前面关于快速排序算法的文字描述我就只写到第一轮交换那里,是因为我认为那是关键核心,那里弄明白了,后续就是他的重复。另外,在注释里我特别解释了递归时表达式里的low与high,是因为有一次我在思考的时候误将这个high一直当作初始的high即arr.length来思考,一度让我走进死胡同,low也是如此。
这是我写的第一篇博客,有点生疏,表达上可能有些不恰当的地方,希望各位老师批评指正,如果对你有所帮助,那便是我分享的意义,祝好。