不稳定的快速排序

1. 思路

每次以末尾数字为基数,比它大的放右边,小的放左边,全排完就好了。

2. 过程

左右划分,共logN次,每部分以最右边为基准再划分 小于基准 等于基准 大于基准的部分,
返回【和基准相等的数a1,和基准相等的数a2】,此时这部分的数就排好了,左右再划分剩下的,所有小的、所有大的

3. 代码

 public  void quickSort(int[] arr) {
        if (arr == null || arr.length < 2) {
            return;
        }
        int N = arr.length;
        //随机一个数和末尾数交换
        swap(arr, (int) (Math.random() * (N)), N - 1);
        //全范围迭代
        int[] equalsArea = neitherlandsFlag(arr, 0, N - 1);
        //获取当前基准的左部分和有部分边界值(包含)
        int leftArea = equalsArea[0];
        int rightArea = equalsArea[1];
        Stack<Op> stack = new Stack();
        //左右分别迭代
        stack.push(new Op(0, leftArea - 1));
        stack.push(new Op(rightArea + 1, N - 1));
        while (!stack.isEmpty()) {
            Op op = stack.pop();
            if (op.left < op.right) {
                //如果左边小于右边,继续迭代
                swap(arr, (int) (op.left + (Math.random() * (op.right - op.left + 1))), op.right);
                //在当前子范围继续拆分左右部分
                equalsArea = neitherlandsFlag(arr, op.left, op.right);
                leftArea = equalsArea[0];
                rightArea = equalsArea[1];
                stack.push(new Op(op.left, leftArea-1));
                stack.push(new Op(rightArea+1, op.right));
            }
        }

    }

    class Op{
        int left;
        int right;

        Op(int left, int right) {
            this.left = left;
            this.right = right;
        }
    }
    public static void swap(int[] arr, int i, int j) {
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }    

  public static int[] neitherlandsFlag(int[] arr, int L, int R) {
        if (L > R) {
            return new int[]{-1, -1};
        }
        if (L == R) {
            return new int[]{L, L};
        }
        //小于基准数的左边界
        int less = L - 1;
        //大于基准数的右边界
        int more = R;
        int cur = L;
        while (cur < more) {
            if (arr[cur] == arr[R]) {
                //如果当前数和基准数相同
                cur++;
            } else if (arr[cur] < arr[R]) {
                //当前数比基准数小
                swap(arr, less + 1, cur);
                less++;
                cur++;
            } else if (arr[cur] > arr[R]) {
                more--;
                swap(arr, cur, more);
            }
        }
        //交换基准数和 大于基准数的最小边界值
        swap(arr, more, R);
        return new int[]{less + 1, more};
    }

4. 时间复杂度 O(n*logn)

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值