快速排序
介绍
快排是一种复杂度O( n l o g ( n ) nlog(n) nlog(n))的排序算法,在极端情况下会退化为O( n 2 {n}^2 n2),但是它是一种原地算法,即不需要占据额外空间
原理是先在数列中取一个数x
,这个数一般随机选取或是取中间值,然后将所有比x
小的数移动到其一侧,大的数移动到其另一侧。然后将左右两堆数视为两个新的数列,再进行上述操作,直到递归结束。
因此可以发现,快速排序的核心是先排序后递归。
核心思想:
问题在于如何排序,具体步骤如下:
- 第一步:设定两个指针
i,j
- 第二步:如果
i<j
,则进行指针移动,左指针不断右移直到指向的数比x大,右指针则相反 - 第三步:如果
i<j
,则交换i
和j
两个指针的数字,此时指针不动,并进行第二步
这样操作结束之后,区间的数字就被排序完成了,复杂度为O(n)。
模板代码:
void quick_sort(int q[N], int l, int r)
{
if ( l >= r ) return; // 递归终止条件
int i = l - 1, j = r + 1, x = q[l + r >> 1];// 定义左右指针和x
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);
}
例题
思路:
按上述模板进行书写即可
代码:
#include<iostream>
using namespace std;
const int N = 1e6 + 10;
int n;
int q[N];
void quick_sort(int q[N], int l, int r)
{
if(l >= r) return;
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 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]);
}