随机化极快排序的分治实现(java)
一,为什么要进行随机化快速排序?
快速排序的时间复杂度为:
最好的情况:O(nlogn)
最坏的情况:O()
由此我们可知,时间复杂度会因为固定主元的选取和次序的不一致而发生变化,如何摆脱输入导致最坏情况。
数组划分时选取固定位置主元,可以针对性构造最差情况。
数组划分时选取随机位置主元,无法针对性构造最差情况。
二,了解分治思想在快速排序中的实现
1,归并排序:重在合并,合并子问题
2,快速排序:侧重分解,简化合并
3,由此可见,分治思想在快速排序中的重点就是数组划分
三,数组划分伪代码
四,快速排序伪代码
五,代码编译
1,代码框架
-
import java.util.Arrays;
-
-
public class QuickSort {
-
public void ToQuickSort(int[] arr,int p,int q){
-
-
}
-
public int Partition(int[] arr,int p,int r){
-
-
}
-
public static void main(String[] args) {
-
QuickSort quicksort=new QuickSort();
-
int[] arr={2,1,3,4,7,5,6,6};
-
System.out.println(Arrays.toString(arr));
-
quicksort.ToQuickSort(arr,0,arr.length-1);
-
System.out.println(Arrays.toString(arr));
-
}
-
}
2,如何生成随机数
在Java语言中生成随机数相对来说比较简单,因为有一个现成的方法可以使用。在Math类中,Java语言提供了一个叫做random的方法。通过这个方法可以让系统产生随机数。不过默认情况下,其产生的随机数范围比较小,为大于等于0到小于1的double型随机数。虽然其随机数产生的范围比较小,不能够满足日常的需求。如日常工作中可能需要产生整数的随机数。其实,只要对这个方法进行一些灵活的处理,就可以获取任意范围的随机数。
如我们可以先通过random方法生成一个随机数,然后将结果乘以10。此时产生的随机数字即为大于等于0小于10的数字。然后再利用Int方法进行转换(它会去掉小数掉后面的数字,即只获取整数部分,不是四舍五入)。最后即可获取一个0到9的整数型随机数字。其实现方法很简单,就是对原有的random方法按照如下的格式进行变型:(int)(Math.Random()*10)即可。其实我们还可以对这个方法进行扩展,让其产生任意范围内的随机数。至需要将这个10换成n即可,如改为(int)(Math.Random()*n)。此时应用程序就会产生一个大于等于0小与n之间的随机数。如将n设置为5,那么其就会产生一个0到5之间的整数型的随机数。如果将这个写成一个带参数的方法,那么只要用户输入需要生成随机数的最大值,就可以让这个方法来生成制定范围的随机数。注:这里random的取值范围始终是[0,n),如果要生成负随机数,就0-(int)(Math.Random()*n),这样就生成(-n,0]的随机数了。
3,一次数组划分后的步骤
再根据伪代码进行分治求解就出来了。
4,完整代码
-
import java.util.Arrays;
-
public class QuickSort {
-
public void ToQuickSort(int[] arr,int p,int r){
-
if(p<r){
-
int q=Partition(arr,p,r);
-
ToQuickSort(arr,p,q-1);
-
ToQuickSort(arr,q 1,r);
-
}//递归入口(p<r)和出口
-
}
-
public int Partition(int[] arr,int p,int r){
-
//取一个范围在[0,r-p 1)的随机数,本题中范围为[0,8),然后递归求解
-
int RandomLocation=p (int)(Math.random()*(r-p 1));
-
//把随机主元放在数组末尾
-
int temp=arr[RandomLocation];
-
arr[RandomLocation]=arr[r];
-
arr[r]=temp;
-
int x=arr[r];
-
//数组中的元素和主元比较
-
int i=p-1;//i代表较小元素的集合坐标,j代表较大元素的集合坐标
-
for(int j=p;j<=r-1;j ){
-
if(arr[j]<=x){
-
int temp1=arr[i 1];
-
arr[i 1]=arr[j];
-
arr[j]=temp1;
-
i=i 1;/*!第一次编译出现错误的地方,i没有向后递加!*/
-
}
-
}
-
//把主元放在适当位置
-
int temp2=arr[i 1];
-
arr[i 1]=arr[r];
-
arr[r]=temp2;
-
return i 1;//返回划分位置
-
}
-
public static void main(String[] args) {
-
QuickSort quicksort=new QuickSort();
-
int[] arr={2,1,3,4,7,5,6,6};
-
System.out.println(Arrays.toString(arr));
-
quicksort.ToQuickSort(arr,0,arr.length-1);
-
System.out.println(Arrays.toString(arr));
-
}
-
}
5,出现问题
主要集中在划分位置函数Partition
-
public int Partition(int[] arr,int p,int r){
-
//取一个范围在[0,r-p 1)的随机数,本题中范围为[0,8),然后递归求解
-
int RandomLocation=p (int)(Math.random()*(r-p 1));
-
//把随机主元放在数组末尾
-
int temp=arr[RandomLocation];
-
arr[RandomLocation]=arr[r];
-
arr[r]=temp;
-
int x=arr[r];
-
//数组中的元素和主元比较
-
int i=p-1;//i代表较小元素的集合坐标,j代表较大元素的集合坐标
-
for(int j=p;j<=r-1;j ){
-
if(arr[j]<=x){
-
int temp1=arr[i 1];
-
arr[i 1]=arr[j];
-
arr[j]=temp1;
-
i=i 1;/*!第一次编译出现错误的地方,i没有向后递加!*/
-
}
-
}
-
//把主元放在适当位置
-
int temp2=arr[i 1];
-
arr[i 1]=arr[r];
-
arr[r]=temp2;
-
return i 1;//返回划分位置
-
}
int RandomLocation=p (int)(Math.random()*(r-p 1));
这里给随机位置加上p,p是数组的首元素,对数组划分后数组一分为二,如果不加p,对前一个数组没啥影响,但是后一个数组的首元素的位置就没法计算了,因此加上这个p的同时,用r-p 1来计算数组的长度,这样后一个数组的随机位置划分也就可以计算了。
int temp=arr[RandomLocation]; arr[RandomLocation]=arr[r]; arr[r]=temp; int x=arr[r];
这里将随机主元放在数组末尾,也就是默认以末尾为固定主元的方式来快排,随机主元的设定只是对划分位置进行随机,快排方式不变。
数组结束排列后,还要将随机主元放回合适的位置,然后进行下一次递归。
for(int j=p;j<=r-1;j ){ if(arr[j]<=x){ int temp1=arr[i 1]; arr[i 1]=arr[j]; arr[j]=temp1; i=i 1;/*!第一次编译出现错误的地方,i没有向后递加!*/ } }
i和j要根据情况进行变化。
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhfiikgc
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
excel下划线不显示怎么办
PHP中文网 06-23 -
怎样阻止微信小程序自动打开
PHP中文网 06-13 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
photoshop蒙版画笔没反应怎么办
PHP中文网 06-24