Java快速排序,思路:选择一个基准数将数组利用递归二分,直到数组不能再分为止;
步骤:(降序)
1、选择一个基准数(本文选择数组第一个数作为基准数);(后面称基准数为A)
2、用A将数组分为2部分:比A小的在右边,比A大的在左边;经过这一步 操作之后,就将整个数组分为了2个数组;
3、分别对左右两边的数组,重复上诉1,2步操作;
4、退出递归的条件,数组长度length =1;
实现代码:
public void xx(int a[],int left,int right) {
if(left < right) {//递归出口条件判断
int x = a[left];
int i=left;
int j = right;
//整个循环目的:用基准数x,将数组分为2个部分(准确来讲是3部分->【左数组】,x,【右数组】)
while(i<j) {
/**从后往前比较*/
while(i < j && a[j] <= x)
j--;
if(i < j) {
a[i]=a[j];
i++;
}
/**从前往后比较*/
while(i<j && a[i] > x)
i++;
if(i<j) {
a[j]=a[i];
j--;
}
}
a[i]=x;
xx(a,left,i-1);//左边数组
xx(a,i+1,right);//右边数组
}
}
以上就是快速排序的实现;
之前在知乎上看到一个问题,如何利用快速排序找一个乱序数组的中位数?
这个问题给出一个条件:在确定数组,可以已知中位数对应的下标;这个问题其实可以转化为求确定下标对应的数值;
从上面的算法中很容易看出,其实快速排序每一次都会给出基准数在该数组排序之后的正确下标;
利用快速排序求数组中位数的思路:
1、算出中位数下标:M
2、以数组第一个数作为基准数,找出该基准数的下标B,与M相比较,找出中位数所在数组;
3、重复步骤2,
4、递归出口:B==M,数组长度length=1;
代码实现:(升序)
public int midian(int []a,int left,int right,int target) {
if(left < right) {
int i = left;
int j = right;
int x = a[left];
while(i < j ) {
while(i < j && a[j] >= x)
j--;
if(i<j) {
a[i]=a[j];
i++;
}
while(i < j && a[i] <= x)
i++;
if(i<j) {
a[j]=a[i];
j--;
}
}
a[i] = x;
/**在每次定位好基准数之后,比较下标*/
if(i == target)
return a[i];
if(i > target) {
return midian(a,left,i-1,target);
}
if(i<target) {
return midian(a,i+1,right,target);
}
}
return a[left];
}
其中target是中位数下标,这个在给定数组之后自己可以算出;
这里有个问题,如果数组元素是偶数,中位数应该是最中间2个数的平均值,应该2次求解找平均值;
可以改进这个算法;