传送门:洛谷 P1177
吐槽
坑爹的数据,目测有一堆重复的元素。
优化
- 对于枢轴的优化:
三点取中法( l , m i d , r l,mid, r l,mid,r取三点中间值)
随机数法(随机数) - 对于排序方法优化:
与其他排序方法混用( E g . Eg. Eg.在范围较小时直接用插入排序)
将相同的元素聚集在一起 - 栈模拟递归
代码
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <stack>
#define IL inline
using namespace std;
IL int read()
{
char c = getchar();
int sum = 0 ,k = 1;
for(;'0' > c || c > '9'; c = getchar())
if(c == '-') k = -1;
for(;'0' <= c && c <= '9'; c = getchar()) sum = sum * 10 + c - '0';
return sum * k;
}
int num[100005];
IL void swap_(int &x, int &y) { int tmp = x; x = y; y = tmp; }
/*IL int get_mid(int x, int y, int z)
{
if(num[x] <= num[z])
{
if(num[y] <= num[x]) return x;
if(num[y] >= num[z]) return z;
return y;
}else
{
if(num[y] <= num[z]) return z;
if(num[y] >= num[x]) return x;
return y;
}
}*/
//随机数生成,参数自己设
IL int rand()
{
static int seed=233;
return seed=int(seed*48271LL%19260817);
}
IL int get_p(int l, int r)
{
return rand() % (r - l + 1) + l;
}
IL int part_sort(int l, int r)
{
//三点取中法
///swap_(num[r], num[get_mid(l, (l + r) >> 1, r)]);
//随机数法
swap_(num[r], num[get_p(l, r)]);
int key = num[r];
for(;l < r;)
{
for(;l < r && num[l] <= key; ++l); if(l < r) num[r] = num[l];
for(;l < r && num[r] >= key; --r); if(l < r) num[l] = num[r];
}
num[r] = key;
return r;
}
IL void quick_sort(int l, int r)
{
//递归版
/*if(l >= r) return ;
int p = part_sort(l, r);
quick_sort(l, p - 1);
quick_sort(p + 1, r);*/
//非递归版
stack<int>stk;
stk.push(l); stk.push(r);
for(int p1, p2, p; !stk.empty();)
{
r = stk.top(); stk.pop();
l = stk.top(); stk.pop();
p = part_sort(l, r);
p1 = p - 1; p2 = p + 1;
//将相同元素放在一起
for(;l < p1 && num[p1] == num[p]; --p1);
for(;r > p2 && num[p2] == num[p]; ++p2);
if(l < p1) { stk.push(l); stk.push(p1); }
if(p2 < r) { stk.push(p2); stk.push(r); }
}
}
int main()
{
int n = read();
for(int i = 1; i <= n; ++i) num[i] = read();
quick_sort(1, n);
for(int i = 1; i <= n; ++i) printf("%d ", num[i]);
return 0;
}