随机快排的非递归实现方式(java)

随机快速排序是一种高效的排序算法,它通过随机选择基准元素并进行分区操作,递归地对子序列进行排序。非递归实现使用栈来模拟递归调用,确保了算法的高效执行。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

什么是随机快排

随机快速排序(Randomized Quick Sort)是一种基于比较的排序算法,也称为选择排序。它的核心思想是每次从待排序的序列中随机选择一个元素,将其放到序列的起始位置,然后对序列进行递归排序,直到所有元素都被排序。

随机快排的特点

与传统的插入排序、选择排序等排序算法不同,随机快速排序不需要预先确定一个最终的有序结果,而是每次从待排序的序列中随机选择一个元素,将其放到序列的起始位置,然后对序列进行递归排序。这种方法具有较高的排序效率,但也容易导致排序结果不稳定。

随机快速排序的基本步骤:

1.选择一个基准元素,通常选择序列的第一个或第二个元素。
2.将序列分为两个部分,左侧部分的所有元素都比基准元素小,右侧部分的所有元素都比基准元素大。
3.对左侧部分和右侧部分分别进行上述步骤,直到每个部分只包含一个元素。
4.递归地对左侧和右侧部分进行随机快速排序,直到整个序列都被排序。

注意事项

需要注意的是,随机快速排序的每次选择都是随机的,这样可以保证排序结果的随机性和稳定性。另外,由于随机快速排序的时间复杂度较高,通常只适用于小规模的数据排序。

代码演示

先把分层效果的代码搞出来

public static int[] partition(int[]arr,int L,int R){
        if (L > R){
            return new int[]{-1,-1};
        }
        if (L == R){
            return new int[]{L,R};
        }
        //移动的下标指针
        int index = L;
        //标记左边小于区域的右边界,刚开始没有时,先标记为L - 1 
        int less = L - 1;
        //右边大于区域的左边界,刚开始没有时,定位R 
        int more = R;
        while(index < more){
            if (arr[index] == arr[R]){
            //相等时 不做交换,下标右移一位
                index++;
            }else if (arr[index] < arr[R]){
            //当小于时,左边区域进行交换,less 下标也右移一位.
                Utils.swap(arr,++less,index++);
            }else{
            //和右边more 左边一位进行交换,并且下标左移一位,index 不动,因为新换来的数据还没进行比较
                Utils.swap(arr,index,--more);
            }
        }
        Utils.swap(arr,more,R);
        return new int[]{less+1,more};
    }

非递归的方式进行调用

/**
     * 使用栈来实现.其实也是模拟递归调用的压栈过程
     * 非递归实现
     * @param arr
     */
    public static void quickSort2(int[]arr){
        if (arr == null || arr.length < 2){
            return ;
        }
        int N = arr.length;
        Utils.swap(arr,N - 1,(int)(Math.random()* N ));
        int[]help = netherlandsFlag(arr,0,N - 1);
        //我们自己用堆栈来实现类似递归的调用
        Stack<Op> stack = new Stack();

		//将两个边界分别压进栈
        stack.push(new Op(0,help[0]-1));
        stack.push(new Op(help[1]+1,N - 1));
        while (!stack.isEmpty()){
            Op op = stack.pop();
            if (op.l < op.r){
                Utils.swap(arr,op.r, (int)((Math.random()*(op.r - op.l + 1))) + op.l );
                int[] ops = netherlandsFlag(arr,op.l,op.r);
                stack.push(new Op(op.l,ops[0]-1));
                stack.push(new Op(ops[1]+1,op.r));
            }
        }

    }

辅助类

public static class Op{
        public int l; //左边界
        public int r; //右边界

        public Op(int l, int r) {
            this.l = l;
            this.r = r;
        }
    }

随机快排的递归实现方式

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值