快速排序原理

快速排序

模板题目

LGOJ模板题:P1177 【模板】快速排序
既然名字都叫快速排序,辣么我们就用快速排序来做(笑)。

思路简介

快速排序和归并排序一样,也是基于一种分治法。
我们设void Qsort(int l, int r)表示将 [ l , r ] [l,r] [l,r]区间排好序。
每排一次:
我们先找到 [ l . r ] [l.r] [l.r]的中位数 v a l val val
然后从前、从后分别设两个指针 i , j i,j i,j,分别从前、从后寻找符合条件的元素。
什么叫做符合条件的元素呢?
对于 i i i指针,如果 a [ i ] ≥ v a l a[i]\geq val a[i]val,也就是说 i i i号元素本来在中位数 v a l val val后,那么它的位置不太对,它 a [ i ] a[i] a[i]就是符合条件的元素
对于 j j j指针,如果 a [ j ] ≤ v a l a[j]\leq val a[j]val,也就是说 j j j号元素本来在中位数 v a l val val后,那么它的位置不太对,它 a [ j ] a[j] a[j]就是符合条件的元素
找到了这两个元素后,如果 i ≤ j i\leq j ij,也就是说满足了 i ≤ j   a n d   a [ i ] ≥ a [ j ] i\leq j \ and \ a[i]\geq a[j] ij and a[i]a[j],我们就把它们交换,就是这样。
这样一次排序完后,我们实际上可以把整个区间分为三部分:
1) 区间 [ l , j ] [l,j] [l,j]和区间 [ i , r ] [i,r] [i,r]这两个区间里的元素分别是 &lt; v a l &lt;val <val &gt; v a l &gt;val >val的,它们区间的相对位置已正确,我们只要递归地进行排序:

Qsort(l, j);
Qsort(i, r);

即可
2) 区间 [ j , i ] [j,i] [j,i]。这里面的元素是 = v a l =val =val的,那还排它干啥。
完美。实际代码记得判边界哦。

详细代码

#define USEFASTERREAD 1 

#define rg register
#define inl inline
#define DEBUG printf("[Passing [%s] in line %d.]\n", __func__, __LINE__)
#define putline putchar('\n')
#define putsp putchar(' ')
#define Rep(a, s, t) for(rg int a = s; a <= t; a++)
#define Repdown(a, t, s) for(rg int a = t; a >= s; a--)
typedef long long ll;
#include<cstdio>
#define rs freopen("test.in", "r", stdin), freopen("test.out", "w", stdout)

#if USEFASTERREAD
char In[1 << 20], *ss = In, *tt = In;
#define getchar() (ss == tt && (tt = (ss = In) + fread(In, 1, 1 << 20, stdin), ss == tt) ? EOF : *ss++)
#endif
struct IO
{
	void RS() {rs;} 
	template<typename T> inline IO r(T& x)const
	{
	    x = 0; T f = 1; char ch = getchar();
	    for(; ch < '0' || ch > '9'; ch = getchar()) if(ch == '-') f = -1;
	    for(; ch >= '0' && ch <= '9'; ch = getchar()) x = x * 10 + int(ch - '0');
	    x *= f; return *this;
	}
	template<typename T> inline IO w(T x)const
	{
	    if(x < 0) {putchar('-'); x = -x;}
	    if(x >= 10) w(x / 10);
	    putchar(x % 10 + '0'); return *this;
	}
	template<typename T> inline IO wl(const T& x)const {w(x), putline; return *this;}
	template<typename T> inline IO ws(const T& x)const {w(x), putsp; return *this;}
	inline IO l() {putline; return *this;}
	inline IO s() {putline; return *this;}
}io;
template<typename T> inline T Max(const T& x, const T& y) {return y < x ? x : y;}
template<typename T> inline T Min(const T& x, const T& y) {return y < x ? y : x;}
template<typename T> inline void Swap(T& x, T& y) {T tmp = x; x = y; y = tmp;}

int N;
int A[100005];
void Qsort(int l, int r)
{
	if(l >= r) return;
	int val = A[(l + r) >> 1];
	int i = l, j = r;
	while(i <= j)
	{
		while(i <= r && A[i] < val) i++;
		while(j >= l && A[j] > val) j--;
		if(i <= j) Swap(A[i], A[j]), i++, j--;
	}
	Qsort(l, j);
	Qsort(i, r);
}


int main()
{
    //io.RS();
    io.r(N);
    for(rg int i = 1; i <= N; i++) io.r(A[i]);
    Qsort(1, N);
    for(rg int i = 1; i <= N; i++) io.ws(A[i]);
    return 0;
}

时空分析

快速排序的最优时间复杂度为 O ( n l o g 2 n ) O(nlog_2n) O(nlog2n),最坏时间复杂度为 O ( n 2 ) O(n^2) O(n2),平均时间复杂度为 O ( n l o g 2 n ) O(nlog_2n) O(nlog2n)

稳定性

快速排序是一种不稳定的排序

STL

C++ STL标准中,在algorithm头文件里提供了sort()函数,可以用来快速排序。一般我们排序都用它。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

日居月诸Rijuyuezhu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值