应用
快速排序,适合于可以随机访问的容器(vector, 数组),不适合链表。不稳定排序。最坏情况 O ( n 2 ) O(n^2) O(n2),取决于pivot的选择。
方法
划分过程:选择一个pivot,将数组划分为左右两段,左段小于等于pivot,右段大于等于pivot。
将划分过程左右两段进行递归。
模版
两种模版,只是划分过程和取pivot的方式不同。
交换法
void quick_sort(vector<int> &q, int l, int r)
{
if (l >= r) return;
// 为了方便在while循环中交换后i++和j--
// 所以初始化时i=l-1, j=r+1,然后在while循环中用do while先做一次更新
int i = l - 1, j = r + 1, x = q[l + r >> 1];
while (i < j)
{
do i ++ ; while (q[i] < x);
do j -- ; while (q[j] > x);
if (i < j) swap(q[i], q[j]);
}
quick_sort(q, l, j), quick_sort(q, j + 1, r);
}
空洞法
int partition(vector<int>& arr, int s, int e){
int pivot = arr[s];
int i = s, j = e;
while(i < j){
// 注意arr[j] >= pivot,等号不可以少。处理有重复元素的情况。
while(i < j && arr[j] >= pivot){
j--;
}
if(i < j){
arr[i] = arr[j];
}
while(i < j && arr[i] <= pivot){
i++;
}
if(i < j){
arr[j] = arr[i];
}
}
arr[i] = pivot;
return i;
}
void quick_sort(vector<int>& arr, int s, int e){
// 递归划分
if(s >= e) return;
int mid = partition(arr, s, e);
quick_sort(arr, s, mid-1);
quick_sort(arr, mid+1, e);
}