一、快速排序法分析
算法思想:
现将4(实际中是第一个元素)移动到它排好序之后的正确位置,那么左边的都是小于4的,右边的元素都是大于4的:
对小于4这部分元素的和大于4的这部分元素分别继续使用快速排序法,逐渐递归下去。
将第一个元素放到正确的位置:
二、快速排序法代码
public class KuaiSuPaiXu {
//arr[l...r]部分进行快速排序
private static void quickSort(int[] arr,int l,int r){
if( l >= r ) return;
int p = partition(arr,l,r); //找到中间位置
quickSort(arr,l,p-1);
quickSort(arr,p+1,r);
}
//首先将第一个元素移动到排好序之后应该放的位置
//使得p之前的元素都小一些,p之后的元素都大一些
//返回p,使得arr[ l ... p-1 ] < arr[ p ]
//arr[ p + 1 ... r] > arr[ p ]
private static int partition(int[] arr,int l,int r){
int v = arr[l]; //取出第一个元素
int j = l; //j表示小于第一个元素和大于第一个元素的分界点
//当前访问的元素称为i
for( int i = l + 1;i <= r;i++ ){
//将所有小于第一个元素的值的元素全部都放到它的左边
if( arr[i] < v ){ //如果当前元素小于v,则交换
swap(arr,i,j+1);
j++;
}
}
swap(arr,l,j); //将第一个元素和中间的元素进行交换
return j;
}
public static void main(String[] args){
int array[] = {1,2,4,3,9,7,8,6};
quickSort(array,0,array.length-1);
for( int i = 0 ; i < array.length ; i++ ){
System.out.print(array[i]+" ");
}
}
static void swap(int[] arr,int a,int b){
int temp = 0;
temp = arr[a];
arr[a] = arr[b];
arr[b] = temp;
}
}
运行结果:
1 2 3 4 6 7 8 9
三、快速排序法的问题以及改进
当数据的量比较少的时候,直接用插入排序法效率高,所有加以优化:
private static void quickSort(int[] arr,int l,int r){
if( l >= r ) return;
if(r - l <= 15)
ChaRuPaiXu.ChaRuPaiXuFa2(arr,l,r);
int p = partition(arr,l,r); //找到中间位置
quickSort(arr,l,p-1);
quickSort(arr,p+1,r);
}
当数组近乎有序的时候,快速排序法的效率特别低。最差的时候为O(n^2)。所有继续优化。
四、随机化快速排序法
之前我们每次取的时候都是用的第一个元素,现在我们随机取出元素作为参考值,这样为O(n^2)的概率变得特别小,算法效率为O(nlogn):
private static int partition(int[] arr,int l,int r){
/****************添加代码**********************/
//随机取出一个元素,然后交换
Random rm = new Random();
int rm1 = rm.nextInt( r - l + 1);
swap(arr,l,rm1 + l);
/*********************************************/
int v = arr[l]; //取出第一个元素
int j = l; //j表示小于第一个元素和大于第一个元素的分界点
//当前访问的元素称为i
for( int i = l + 1;i <= r;i++ ){
//将所有小于第一个元素的值的元素全部都放到它的左边
if( arr[i] < v ){ //如果当前元素小于v,则交换
swap(arr,i,j+1);
j++;
}
}
swap(arr,l,j); //将第一个元素和中间的元素进行交换
return j;
}
五、双路快速排序法
如果数组中的元素有很多重复元素的话,快递排序效率很差。我们采用双路快速排序方法:
private static int partition2(int[] arr,int l,int r){
//随机取出一个元素,然后交换
Random rm = new Random();
int rm1 = rm.nextInt( r - l + 1);
swap(arr,l,rm1 + l);
int v = arr[l]; //取出第一个元素
int i = l + 1,j = r;
while (true){
while ( i <= r && arr[i] < v) i++;
while ( j <= l + 1 && arr[j] > v) j--;
if( i > j ) break;
swap(arr,j,j);
j++;
j--;
}
swap(arr,j,l);
return j;
}
转载请标明出处,原文地址:https://blog.csdn.net/weixin_41835916
总结整理不容易,如果觉得本文对您有帮助,请点击顶支持一下,您的支持是我写作最大的动力,谢谢。