快速排序算法流程
一.选取中轴元素,然后通过下述过程将原数组分为3部分,分别为(arr[low],arr[j-1]),arr[j],(arr(j+1),arr[high])
1.选取第一个元素为中轴元素,i为数组开始下标,j为数组为的结尾下标。
2.i下标所指向的元素从左往右依次与中轴元素比较大小,直到遇到比中轴元素大(或等于)的元素。 j下标所指向的元素从右往左依次与中轴元素比较大小,直到遇到比中轴元素小(或等于)的元素。
3.如果此时 i<j 则交换i、j所指向的元素,然后继续相向而行,直到i>=j;此时i对应的元素左边(不包括arr[i])必定小于或等于中轴元素 此时j对应的元素右边(不包括arr[j])必定大于或等于中轴元素,所以此时将arr[j]与开头元素交换位置。arr[j]为新的中轴元素。
/*选取中轴元素*/
public int partition(int arr[],int low,int high){
int i=low,j=high+1;
int v=arr[low];
while(true){
//从左往右依次与中轴元素比较大小,直到遇到比中轴元素大(或等于)的元素,break(所以是小于v)
while(arr[++i]<v){if(i==high) break;}//i==high防止数组越界
//从右往左依次与中轴元素比较大小,直到遇到比中轴元素小(或等于)的元素,break
while(arr[j--]>v){if(j==low) break;}
if(i>=j){break;}//说明此时不再需要进行移动
swap(arr,i,j);//如果此时 i<j 则交换i、j所指向的元素,
}
swap(arr,low,j);//新的中轴元素选出
return j;
}
public void quickSort (int arr[],int low,int high){
if(low<high){
int j=partition(arr[],low,high);
quickSort(arr[],low,j-1);
quickSort(arr[],j+1,high);
}
}
快速排序时间复杂度
平均情况为O(nlogn)
最坏情况(原数组为有序数组)下可能为O(n^2)
最好情况(每次选到的中轴元素刚好位于中间)O(nlogn)
快排之所以快,就是因为它高度优化的内部循环(分割)
它既不像归并排序那样需要辅助数组来回复制元素
也不像堆排序无法利用缓存并且有许多无用的比较,并且最坏情况可以采用方法避免
稳定性
不是稳定的,如果数组中有与中轴元素相同元素,还是会发生交换。