快速排序
思想
基于划分的思想,假设选择数组最左边的元素作为枢纽,一指针从数组最左边开始,寻找大于枢纽的元素,另一指针从数组最右边开始,寻找小于枢纽的元素,然后交换两指针位置上值,直到指针重合,交换指针与数组最左边的元素,这样枢纽左边的元素都比枢纽小,枢纽右边的元素都比枢纽大。
示例
关键代码
//找出分界点
public static int partition(int[] array,int begin,int end){
int i=begin;
int j=end;
int pivot=begin;//枢纽位置
int pivotNum=array[pivot];
while(i<j){
int temp;
//如果先从左边开始时,那么最终 i 所停留的那个交换位置值肯定是大于基数
while(array[j]>pivotNum&&i<j) j--;
while(array[i]<=pivotNum&&i<j) i++;
//找出左边比枢纽大的数与右边比枢纽小的数进行交换,直到i与j相遇
temp=array[j];
array[j]=array[i];
array[i]=temp;
}
if(i==j){
//交换枢纽与分界点的值,达到枢纽左边比枢纽小、右边比枢纽值大的效果
int temp;
temp=array[i];
array[i]=array[pivot];
array[pivot]=temp;
}
return i;
}
public static void QuickSort(int[] array,int begin,int end){
if(begin<end){
int q;
q=partition(array,begin,end);
QuickSort(array,begin,q-1);
QuickSort(array,q+1,end);
}
}
复杂度
快速排序之所比较快,因为相比冒泡排序,每次交换是跳跃式的。每次排序的时候设置一个基准点,将小于等于基准点的数全部放到基准点的左边,将大于等于基准点的数全部放到基准点的右边。这样在每次交换的时候就不会像冒泡排序一样每次只能在相邻的数之间进行交换,交换的距离就大的多了。因此总的比较和交换次数就少了,速度自然就提高了。当然在最坏的情况下,仍可能是相邻的两个数进行了交换。因此快速排序的最差时间复杂度和冒泡排序是一样的都是O(N2),它的平均时间复杂度为O(NlogN)。