快速排序释义
快速排序是一种高效率的排序,通过对一组无序数组,任意的抽出一个数作为基准值,使得所有比它小的在他的左边/右边,比他大的数在它的右边/左边。在学习java数组的相关知识的时候,一定会接触的到的重要算法。记得最开始的时候,学习冒泡的时候很难,但是理解之后感觉冒泡排序和后面学到的选择排序相对来说是比较"老实"的算法,每次交换没有快排的跳跃度大,所以也是查找了不少资料和相关视频来弄懂这个算法,接下来会以最详细的方式来解读快速排序算法。
基本思路和理解
在一组无序的数组内,我们可以任意抽出一个元素,将他记录为基准元素,通过这个基准元素,将数组内其他的所有元素和它进行对比,然后以这个基准元素为分割线,将这个数组分成两个子数组,然后再对这两个子数组进行递归则最终可以获得一组有序的数组。
先用漫画的形式来初步理解排序的过程:
此图来自CSDN的其他博主的,仅借鉴参考,漫画图来源于《啊哈!算法》
在开始code之前,我们先需要对通过引入一些实际概念来理解这整个排序过程。因为代码中的排序过程是抽象的,我们需要画图也就是实例的方式来去理解这段程序在执行过程中的抽象过程。
先定义一组数组:
上述已经命名的变量会在后续的代码中出现,需要先记住,code如下
public class Quickly_Sort {
public static void main(String[] args) {
int [] arr = {5,6,8,3,1};
quick(arr,0,arr.length-1);
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
}
public static void quick(int[] arr,int origin_index, int ending_index){
if (arr == null || arr.length == 0) {
return;
}
if (origin_index > ending_index){
return;
}
int Standard_value = arr[origin_index];
int Left_start_cursor = origin_index;
int Right_start_cursor = ending_index;
while (Left_start_cursor != Right_start_cursor){
while (arr[Right_start_cursor] >= Standard_value && Left_start_cursor < Right_start_cursor){
Right_start_cursor
--;
}
while (arr[Left_start_cursor] <= Standard_value && Left_start_cursor < Right_start_cursor){
Left_start_cursor++ ;
}
if (Left_start_cursor < Right_start_cursor){
int temp = arr[Left_start_cursor];
arr[Left_start_cursor] = arr[Right_start_cursor];
arr[Right_start_cursor] = temp;
}
}
arr[origin_index] = arr[Left_start_cursor];
arr[Left_start_cursor] = Standard_value;
quick(arr,origin_index,Left_start_cursor - 1);
quick(arr,Left_start_cursor + 1,ending_index);
}
}
建议把code直接复制到idea中,进行debug,一步一步查看程序是如何运行的
详细Debug运行解析:
接下来我就开始debug将程序进行一步一步的拆分,只要遇到需要交换的情况,建议自行画图加深理解
第一次进入if判空,if(origin_index > ending_index)是否成立
第一次确定基准值,左游标和右游标
第一次进入关于左,右游标不相等的while循环,简称大while循环
while(Left_start_cursor != Right_start_cursor)
第一次右边游标开始与基准值值作比较,并且左游标的值 < 右游标的while循环,
符合条件,则右游标 -1 ,即向左移1位,直到( )内的条件不满足则,跳出循环
PS:
这个地方可以好好的debug并且配合画图来理解,可以加深映像
第一次左游标与基准值左比较,并且左游的值 < 右游标的值 的while循环
符合条件,做左游标+1,即向右移动一位,一直移动到( )内的条件不满足,则跳出循环
PS:这个地方可以好好的debug并且配合画图来理解,可以加深映像
第一次进入到if判断,比较Left_start_cursor < Right_start_cursor 是否成立,成立的话那么就开始进行将左游标和右游标所指向的元素进行位置交换,可以按照我的代码截图的红框的值,想一想会走到这个if判断,前后的因果关系是什么,建议画图,强烈建议!!
等到上述代码执行完成了,那么就会又要回到大while循环,就是第一个while,也就是 (第二次判断) ‘’ if(origin_index > ending_index)是否成立
PS:注意观察这个时候数组的变化,还有左游标,右游标的变化
然后和之前的逻辑一致,进行循环,直到当程序在某次进入到if(Left_start_cursor < Right_start_cursor),发现不成立,然后立刻回到大while循环的时候条件也不成立,那么就执行以下代码,注意看这个时候的红框内的值。
然后,这两行代码完成之后,就第一次完成了基准值的更换
接下来的两行代码开始进行递归,且上面一行5左边的子数组{3,1},下面的一行是5右边的{8,6}
等两个递归方法完成后,结果就能输出来了:**
Ps:
一瞬间看不懂的代码,一定要学会debug,并且配合画图,打草稿清楚每一个步骤,这样才能加深理解,明白通透