美文网首页
关于快排

关于快排

作者: 三斤牛肉 | 来源:发表于2020-12-22 15:56 被阅读0次

最近在撸快排,发现网上写的千篇一律,理论定义的步骤和代码稍有些区别,所以按我自己理解的在整理一遍
首先抄一下网上的定义和模拟图:

  • 从数列中挑出一个元素,称为 “基准”(pivot);重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。
  • 在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作;
  • 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。
    image.png
    从动图就可以看到开始时候基准为array[0],当比较比array[0]小时,放到array[0]后面,
    image.png
    现在有这么个数组:
    [6,2,9,3,5,1,7]
    如果我们按理论的来应该这么做:
    step1:将pivot设为第一个值6,找到比6小的值2:[6,2,9,3,5,1,7]
    step2:将2放到6前面[2,6,9,3,5,1,7]
    step3:同上将3放到6前面[2,3,6,9,5,1,7]
    ... : [2,3,1,5,6,9,7]
    然后将2,9(6的下一个)作为pivot递归继续
    这是正常人理解的定义步骤,但却不是代码实现步骤...
    因为你会发现,如果将2放在6前面,需要将2之前的整个数组往后移一位,增加了复杂度。

那么实际代码处理是怎么样的?
用了一个取巧的方式,增加一个指针,将比pivot小的数放到pivot后面,指针后移,最后将pivot和最后的指针位置交换下就可以了。
那么我们来看:
step1:相同,将pivot设为第一个值6,找到比6小的值2:[6,2,9,3,5,1,7],增加一个指针指向pivot后面的位置(下标1)
step2:将2和指针互换位置,由于这里是同一个,不变[6,2,9,3,5,1,7],指针后移到下标2
step3:找到下一个值3,和下标2的值9换位,[6,2,3,9,5,1,7]指针后移到下边3
step4:同上找到5,对列变为[6,2,3,5,9,1,7],指针后移到4
step5:[6,2,3,5,1,9,7],指针到5
step6:将6和最后一个小于6(即是指针之前的一位下标5-1=4)的值换位[1,2,3,5,6,9,7]
后面的流程将6作为pivot分左右两侧继续递归就一样了。
这样比只是在最后循环结束后多了一次交换过程。

网上的样例代码如下:

//Java 代码实现
 public class QuickSort implements IArraySort {
 
     @Override
     public int[] sort(int[] sourceArray) throws Exception {
         // 对 arr 进行拷贝,不改变参数内容
         int[] arr = Arrays.copyOf(sourceArray, sourceArray.length);
 
         return quickSort(arr, 0, arr.length - 1);
    }

    private int[] quickSort(int[] arr, int left, int right) {
        if (left < right) {
            int partitionIndex = partition(arr, left, right);
            quickSort(arr, left, partitionIndex - 1);
            quickSort(arr, partitionIndex + 1, right);
       }
        return arr;
    }

    private int partition(int[] arr, int left, int right) {
        // 设定基准值(pivot)
        int pivot = left;
        int index = pivot + 1;
        for (int i = index; i <= right; i++) {
            if (arr[i] < arr[pivot]) {
                swap(arr, i, index);
                index++;
            }
        }
        swap(arr, pivot, index - 1);
        return index - 1;
    }

    private void swap(int[] arr, int i, int j) {
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }

}

相关文章

  • 关于快排

    最近在撸快排,发现网上写的千篇一律,理论定义的步骤和代码稍有些区别,所以按我自己理解的在整理一遍首先抄一下网上的定...

  • 数据结构:快速排序优化思路

    既然这是一篇主题思想为优化快排的文章,自然就不讨论关于快排的一些定义和基础性的问题,只说快排应该怎么优化。 快排为...

  • 快排

    快排代码

  • 快排

  • 快排

    昨天晚上睡觉前兴起准备十分钟写出快排,结果纠结了两个小时愣是没有搞出来,很郁闷地睡觉去。今天地铁上跟LG又重新缕了...

  • 快排

    基本思想: 先从数列中取出一个数作为基准数。 分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的...

  • 快排

  • 快排

    python实现 java实现:

  • 快排

    快速排序: 基本思想:1、先从数列中取出一个数作为基数。2、分区,将比此基数大的数放到它右边,小的数放到它左边。3...

  • 快排

    package sort;import java.util.Arrays;public class Quickso...

网友评论

      本文标题:关于快排

      本文链接:https://www.haomeiwen.com/subject/lxssnktx.html