随机化快速排序

发布于:2022-12-23 ⋅ 阅读:(214) ⋅ 点赞:(0)

萌新跟着大佬的代码学习了,在学习过程中有一些自己遇见的问题和自己的一些思考过程,浅浅做一下分享,如果有什么不对的地方,欢迎大家指出

思想阐述:

首先我们来讲述一下思想:随机在输入的数组里选出一个数,然后找到它的正确位置(难点),再将这个数(已经到了正确位置)的左右两侧重复上述步骤(以上操作均在同一个数组内完成);

举个例子:

现在有一组数:

 

假设我们的随机数是:2(对应元素4),为了后续方便找到这个数,将4放到left(此时为数组[0]),于是数组变成了这样:

 

我们设置一个p来记录4的正确位置,初始值为left,然后将p的值与后面元素的值依次比较,如果4大,p+1,这个数字与原本再p位置上的数字交换位置

过程:

1<4:p=left+1(0+1) 交换位置也相当于位置不变

4<8:不做处理

3<4:p=p+1(1+1)交换位置

 

2<4:p=p+1(2+1)交换位置

 

4<6:不做处理

 

4与现在在它正确位置上的元素交换位置(也就是p位置上的元素)

 

现在以4为中心将它左右两边分开来排序

先看左边

 

此时left=0 right=2 (原本在数组中的位置,2=p-1)此时p重新设置又等于left(0)

假设随机数是2(2位置上的元素是3)

把3与left位置上的元素交换位置

 

1<3:p=p+1(0+1) 交换位置后仍是现在这样

2<3:p=p+1(1+1) 交换位置后仍是现在这样

将3与现在在它位置上的元素做交换

 

再以3为中心分为左右两列(此时没有右边)

 

此时left=0 right=1(1=p-1),p重置等于left(0)

随机数只能是1(1位置上的元素是1)

把1与left位置上的元素交换位置

 

1<2:不进行操作

p没有改变,此时1与处于正确位置上的元素交换(自己跟自己交换)

以1为中心分为两列(没有左边)

再进行时left=right,2已经在正确位置上了可以跳出递归了

我们再来看右边

 

随机数只能是5(我们并没有新建数组,在原数组中位置为5,对应元素为6),left=4(p+1) right=5(数组长度),p重置等于left

将6与left对应的元素互换位置

 

6<8:不做操作

后面的过程与前边左边最后几步一样

此时元素排列完成

 

遇到的问题,或者自己比较好奇的点

1.

 

为什么有个if(left >= right) 当左边界大于等于右边界时说明此时已经只剩下一个数了,它肯定在正确位置,这个也是跳出递归的步骤

2.

这里最开始错了,因为忽略了右边界是取不到的,大家如果也像我一样不太清除怎么写范围,可以试着举例一组数据 比如位置为8——13 right-left=5 实际表示的数的范围为0——4 加上一个left以后为8——12 因为我们不需要8位置(可以要,只不过本来就在第一位没必要交换,如果要第一位,就写成((right - left + 1)+1),又需要13位置,所以再加1.

3.

 

这里right是位置,所以要取等号,最开始在这出错看了好久!

以上就是一个简单的分享,可能仍然解释得不太清晰,水平有限,感谢观看

代码展示:

package Sort;

public class RandomizedQuickSort {
    public static int partition(int[] a , int left , int right ){
        int r = (int) (Math.random()*(right - left )+ left + 1);//生成的数字范围要为[left+1,right]
        int p = left;//寻找比随机数的正确位置
        int m = a[r];
        exchange(a , left , r);//将随机数挪到第一个位置上去,方便后面找到它把它放在正确位置上
        for (int i = left+1; i <= right; i++) {
            if (m >= a[i]){
                p++;
                exchange(a , p , i);//这样可以把比p小的元素依次放到前面
            }
        }
        exchange(a , left , p);//把随机数放到了正确位置上
        return p;//返会p的值,方便后续的递归
    }

    public static void exchange(int[] a , int i , int j){
        int num = a[i];
        a[i] = a[j];
        a[j] = num;
    }

    public static void quickSort(int[] a ){
        quickSort(a , 0 , a.length-1);
    }

    //递归实现
    public static void quickSort(int[] a , int left , int right){
        if (left >= right){
            return;
        }
        int p = partition(a , left ,right);
        quickSort(a , left , p-1);//左部分
        quickSort(a , p+1 , right);//右部分
    }

    public static void main(String[] args) {
        int[] a =new int[20];
        for (int i = 0; i < 20; i++) {
            a[i] = (int) (Math.random()*100+1);
        }
        for (int m:a
             ) {
            System.out.print(m+" ");
        }
        System.out.println(" ");
        quickSort(a);
        for (int m:a) {
            System.out.print(m+" ");
        }
    }
}

本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到