快速排序
快速排序
快速排序的整体思想就是在待排序数组中寻找一个称为主元(pivot)的元素,将数组分为两个部分,使得第一部分的所有元素都小于或者等于主元;第二部分的所有元素都大于主元。然后分别递归地对第一部分和第二部分进行快速排序。
在最差的情况下,划分n个元素的数组需要进行n次比较和n次移动,所以划分所需时间为O(n)。同时在最差情况下,主元每次划分数组时,会将数组划分为一个大的子数组和一个小的子数组(比如给定的待排序数组已经是一个从大到小排序的数组了),此时花费的时间为(n-1) + (n - 2) + ……+1 ,那么该算法的最终的时间复杂度为O(n * n)。
比较理想的情况是,每次划分都是将数组二等分。时间复杂度为O(nlogn)。平均情况下,也是O(nlogn)。
算法实现:
private void quickSort(int[] a,int first,int last){
if (first < last){
int newPivotIndex = partition(a, first, last);
quickSort(a,first,newPivotIndex - 1);
quickSort(a,newPivotIndex + 1,last);
}
}
private int partition(int[] a,int first,int last){
int pivot = a[first];
int low = first + 1;
int high = last;
while (low < high){
while (low < high && a[low] <= pivot)
low ++;
while (low < high && a[high] > pivot)
high --;
if (low < high){
int temp = a[low];
a[low] = a[high];
a[high] = temp;
}
}
// 寻找主元新的位置,使得新位置的左边都小于主元的值;新位置的右边都大于主元的值
while (high > first && a[high] >= pivot)
high --;
if (pivot > a[high]){
int temp = a[high];
a[high] = pivot;
a[first] = temp;
return high;
}else {
return first;
}
}