之前写过这道题的分享,但是比较粗糙,因此这里想系统记录一遍。
给定你一个长度为 n
的整数数列。
请你使用快速排序对这个数列按照从小到大进行排序。
并将排好序的数列按顺序输出。
输入格式
输入共两行,第一行包含整数 n
。
第二行包含 n
个整数(所有整数均在 1∼109
范围内),表示整个数列。
输出格式
输出共一行,包含 n
个整数,表示排好序的数列。
数据范围
1≤n≤100000
输入样例:
5
3 1 2 4 5
输出样例:
1 2 3 4 5
#include <iostream>using namespace std;const int N = 100010;int n;
int q[N];void quick_sort(int q[], int l, int r)
{if(l >= r) return;//int x = q[l], i = l - 1, j = r + 1; // 分界点确定为q[l]会超时int x = q[(l + r) / 2], i = l - 1, 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]);}quick_sort(q, l , j);quick_sort(q, j + 1, r);
}int main ()
{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]);printf("\n");return 0;
}
这里值得讨论的是:
**在快速排序算法中,选取分界点的方式会影响算法的性能。**如果选取的分界点恰好是数组的最小或最大值,或者数组是已经排序好的情况下,快速排序的性能可能会变得很差,因为每次划分都会得到极度不平衡的子数组,导致递归深度增加,最坏情况下时间复杂度达到O(n^2)。
为了解决这个问题,通常采用的方法是随机选取分界点。(本题中采取中点为分界点)这样可以降低快速排序在最坏情况下的概率,提高算法的平均性能。具体的做法是在待排序数组中随机选择一个元素作为分界点,然后继续进行划分操作。