快速排序是采用分而治之策略的排序算法
核心
partition函数,返回mid位置
使得 arr[begin], arr[begin+1], ..., arr[mid-1] <= arr[mid] <= arr[mid+1], arr[mid+2], ..., arr[end]
partition函数的实现
方案A (partition1):
确定pivot元素(可使用arr[begin]或arr[random]或其他)
2个指针,指针j从end向前寻找arr[j]<pivot
的元素,指针i从begin向后寻找arr[i]>pivot
的元素。如果i, j未相遇,则swap(arr[i], arr[j])
。然后继续扫描,直到i, j相遇。最后swap(pivot, arr[j])
方案B (partition2):
确定pivot元素(可使用arr[begin]或arr[random]或其他), swap(pivot, arr[end])
2个指针,指针k从begin开始待命;指针i从begin开始向后寻找arr[i]<pivot
的元素,如找到,swap(arr[i], arr[k])
,交换完成后,指针k++继续待命; i继续向后搜寻直到 i==end-1
; 最后swap(pivot, arr[k])
时间复杂度
平均 O(NlogN),但比归并排序有更小的时间常数
cpp实现
template <typename T>
void quickSort(T arr[], int begin, int end){
if(begin<end){
int mid;
mid = partition1(arr, begin, end);
quickSort(arr, 0, mid-1);
quickSort(arr, mid+1, end);
}
}
template <typename T>
int partition1(T arr[], int begin, int end){
T pivot=arr[begin];
T tmp;
int iL=begin, iR=end;
while(iL<iR){
while(arr[iR]>pivot && iR>iL){
iR--;
}
while((arr[iL]==pivot || arr[iL]<pivot) && iL<iR){
iL++;
}
if(iL<iR){
//swap
tmp = arr[iL];
arr[iL] = arr[iR];
arr[iR] = tmp;
}
}
tmp = arr[iR];
arr[iR] = pivot;
arr[begin] = tmp;
return iR;
}
template <typename T>
int partition2(T arr[], int begin, int end){
T pivot=arr[begin];
T tmp;
//swap pivot and arr[end]
arr[begin] = arr[end];
arr[end] = pivot;
int iL=begin, iR=begin;
while(iR<end){
if(arr[iR]<=pivot){
if(iR!=iL){
tmp = arr[iR];
arr[iR] = arr[iL];
arr[iL] = tmp;
}
iL++;
}
iR++;
}
tmp = arr[iL];
arr[iL] = arr[end];
arr[end] = tmp;
return iL;
}