数据结构与算法——快速排序详解java

快速排序的思想

  1. 先从数列中去一个数的基准数
    (1)取基准数的方式有几种 一种是取数组中的第一个数,第二种是取数组中的最后的一个数 ,第三种是取第一个和最后一个以及数组中间三个数的中间数
  2. 在分区过程,将这个数大的数全部放到它的右边,小于这个数的数放到它的左边
  3. 在对左右分区重复第二步,直到各区间只有一个数
    快速排序有三种实现方式 挖坑法,左右指针法,以及前后指针法

左右指针法

  1. 选取一个关键字做枢纽,一般都是第一个数或者最后一个数,这里采取的是第一位数
  2. 设置两个变量left = 0;right = N-1;
  3. 从left向后走,一直走到大于key的值,然后停止不动,right从后先前走,直到找到一个比key小的数,然后交换这两个数
  4. 重复第三个数,一直向后找,直到left与right相遇 这个时候讲key放到left的位置就可以了

在这里插入图片描述当left>=right的时候 第一趟快速排序就完成了,这时key与left交换位置 就会出现下面的结果
一次快排的结果:4 1 3 0 2 5 9 8 6 7

    public static void quicklySort(int[] arr, int left, int right) {
        int i, j, t, temp;
        if (left > right) {
            return;
        }
        i = left;
        j = right;
//        基准位我采取的是第一位
        temp = arr[left];
        while (i < j) {
//            先看右边 依次向左递减
            while (temp < arr[j] && i < j) {
                j--;
            }
//            再看左边 依次向右递增
            while (temp >= arr[i] && i < j) {
                i++;
            }
//    上面连个判断当走到这一步的时候 可以发现的是 temp<arr[j]或者 temp    判断两个下标有没有相遇 相遇的话就交换位置
            if (i < j) {
                t = arr[i];
                arr[i] = arr[j];
                arr[j] = t;
            }

        }
//        最后的基准数与low和high相等的位置交换
        arr[left] = arr[i];
        arr[i] = temp;
//        递归调用左边的数组
        quicklySort(arr, left, i - 1);
//递归调用右边的数组
        quicklySort(arr, j + 1, right);
    }

    public static void main(String[] args) {
        int[] arr = {10, 7, 2, 21, 90, 62, 3, 4, 32, 1, 8, 9, 19};
        quicklySort(arr, 0, arr.length - 1);
//        sort(arr, 0, arr.length-1);
        System.out.println(Arrays.toString(arr));
    }

输出[1, 2, 3, 4, 7, 8, 9, 10, 19, 21, 32, 62, 90]

挖坑法

  1. 选取一个数作为枢纽(key),一般取数组的第一个数或者最后一个数,我这里选取的是第一个数作为枢纽
  2. 设置两个变量left = 0; reght = N-1;
  3. 从left一直向前走,直到找到第一个大于key的数,然后把该数放入坑位中,坑位就变成了array[left]
  4. right一直向前走,直到找到第一个小于key的值,将该数放入坑位,坑位就变成了array[right]
  5. 重复3.4步直到right与left相遇,然后将key放进最后一个坑位
    在这里插入图片描述当left >= right时,将key放入最后一个坑,就完成了一次排序。
    注意,left走的时候right是不动的,反之亦然。因为left先走,所有最后一个坑肯定在array[right]。
 public static void main(String[] args) {
        int[] arr = {10, 7, 2, 21, 90, 62, 3, 4, 32, 1, 8, 9, 19};
//        quicklySort(arr, 0, arr.length - 1);
        sort(arr, 0, arr.length-1);
        System.out.println(Arrays.toString(arr));
    }

    /**
     * 快速排序 挖坑法
     *
     * @param arr
     * @param l
     * @param r
     */
    public static void sort(int[] arr, int l, int r) {

        int i = l;
        int j = r;
//        基准点采用的第一个
        int x = arr[l];

        while (i < j) {
            while (i < j && arr[j] > x) {
                j--;
            }
            if (i < j) {
                arr[i++] = arr[j];
            }
            while (i < j && arr[i] < x) {
                i++;
            }
            if (i < j) {
                arr[j--] = arr[j];
            }

        }
        arr[j] = x;
        if (l < i) {
            sort(arr, l, i - 1);
        }
        if (r > i) {
            sort(arr, i + 1, r);
        }
    }

输出[1, 2, 3, 4, 7, 8, 9, 10, 19, 21, 32, 62, 90]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值