快排算法

一、基本思想

从数组中选择一个基准数值,一轮排序之后,基准数值左边的每一个数值比右边的每一个数值小。然后对基准数值左边右边的数值列表再重新排序,直到左边和右边子列表中不需要排序(只有一个数值)。

 

二、流程示例

     

 1、选择基准值,并定义排序区间

选择一个排序基准值,以最左或最右的数值为基准值进行排序。

这里选择最右方的 值=3 当做基准值

      

         思考: 如果选择了最右侧的当做基准值,r 和 l 下标应该是谁先动,有什么区别?

 

 2、下标左移或者右移,进行值比较并赋值

        核心思想:如果你是正序排序,需要将小于基准值的给 l, ,大于基准值的 给 r

如果选择了最右侧的值为基准值,就需要左侧的下标 l 先进行和基准值比较、移动,反之亦然。

①、l 下标先动,判断 l 值为 2,值不动(因为其是小于3的,满足排序规则,处于 l 的扫描范围)。l 下标继续向右移动,直到遇到了 

 

②、发现 4 大于基准值 3,且是在 l 的范围内,不在 r 的范围内,需要将 l下标的值和 r 下标的值 进行交换

思考:这里发生了一次交换,然后应该是谁继续动,有什么区别

 ③、r 向左移动

发现其值为 4 且在 r 的扫描范围内,则 r 继续向左移动

 

 ④、r 向左移动

发现其值小于基准值,且其不在 l 的扫描范围内,则需要将值给 l

 ⑤、l 向右移动 

但是其发现  l 与 r 相撞了,意味着 l + r 已经扫描完整个 区间了,则这一轮排序结束。

 

排序结果为:   比基准值大的都在右边,比基准值小的都在左边

 

现在已经保证 l 扫描范围中的任意值 小于 r 扫描范围中的任意值, 但是不能保证 l 和 r 扫描区间内 各自数值的顺序,需要分别对 l 和 r 扫描区间内部进行排序

3、l 区间 和 r 区间内部排序

         重复对各自区间进行步骤 2 操作即可。

 

三、区间内左移和右移比较算法

 1 private int partition(int[] arr, int left, int right) {
 2         int current = arr[right];
 3         // 以谁未基准就需要反方向先动
 4         while (left < right) {
 5             while (left < right && arr[left] <= current) {
 6                 left++;
 7             }
 8             arr[right]=arr[left];
 9 
10             while (left < right && arr[right]>= current ) {
11                 right--;
12             }
13             arr[left] = arr[right];
14         }
15 
16         arr[right]=current;
17 
18         return left;
19     }

 四、算法示例

 1  public int[] sort(int[] arr) {
 2         quickSort(arr, 0, arr.length - 1);
 3         return arr;
 4     }
 5 
 6     public void quickSort(int[] arr, int left, int right) {
 7         if(left < right){
 8             int middle = partition(arr,left,right);
 9             quickSort(arr,left,middle-1);
10             quickSort(arr,middle+1,right);
11         }
12     }
13 
14     private int partition(int[] arr, int left, int right) {
15         var current = arr[right];
16         //很重要:以谁为基准就需要反方向先动
17         while (left < right) {
18             while (left < right && arr[left] <= current) {
19                 left++;
20             }
21             arr[right]=arr[left];
22 
23             while (left < right && arr[right]>= current ) {
24                 right--;
25             }
26             arr[left] = arr[right];
27         }
28 
29         arr[right]=current;
30 
31         return left;
32     } 
posted @ 2021-05-22 16:55  FCmmmmmm  阅读(400)  评论(0编辑  收藏  举报