快速排序
特点
-
不稳定排序算法
-
平均复杂度O(nlog2(n)), 最坏时间复杂度O(n^2)
快排思想–分支思想(不稳定算法)
-
确定分界点:区间左端点,区间右端点,区间中点,随机选点。 (四选一)
-
调整区间: 让小于等于分界点的值在分界点的左边,让大于等于分界点的值在分界点右边
-
递归处理左右两段
-
具体实现采用双指针方法,指针 i 指向左端, 指针 j 指向右端,每次判断i指针是否小于分界点,j指针是否大于分界点。 当i指针值大于x停止移动,当j指针小于x停止移动,交换i,j指针所指的值,当i==j停止,递归左右区间。
代码实现
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 1e6 + 10;
int q[N];
void quick_sort(int q[], int l, int r)
{
if (l >= r) return;
int x = q[(l + r) / 2]; // int x = q[l + r >> 1]; 如何一组数字是升序,则选择 int x = q[l] 会编程o(n ^ 2)
int i = l - 1;
int j = 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]);
}
printf("%d %d\n", i , j);
// i 是有可能大于 j 的(i >= j),所以分界只能取 [l, j], [j+1, r]; 或者 [l, i-1], [i, r]
// 注意取j时,q[l + r >> 1] 取 i 时, q[l + r + 1 >> 1], 两个模板背住一个就行。取 j 的背住
quick_sort(q, l, j);
quick_sort(q, j + 1, r);
}
int main()
{
int n;
scanf("%d", &n);
for (int i = 0; i < n; i++) scanf("%d", &q[i]);
quick_sort(q, 0, n - 1);
for (int i = 0; i< n; i++) printf("%d ", q[i]);
return 0;
}