萌新跟着大佬的代码学习了,在学习过程中有一些自己遇见的问题和自己的一些思考过程,浅浅做一下分享,如果有什么不对的地方,欢迎大家指出
思想阐述:
首先我们来讲述一下思想:随机在输入的数组里选出一个数,然后找到它的正确位置(难点),再将这个数(已经到了正确位置)的左右两侧重复上述步骤(以上操作均在同一个数组内完成);
举个例子:
现在有一组数:
假设我们的随机数是: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+" ");
}
}
}