快速排序---優化
阿新 • • 發佈:2018-11-10
傳送門:洛谷 P1177
吐槽
坑爹的資料,目測有一堆重複的元素。
優化
- 對於樞軸的優化:
三點取中法( 取三點中間值)
隨機數法(隨機數) - 對於排序方法優化:
與其他排序方法混用( 在範圍較小時直接用插入排序)
將相同的元素聚集在一起 - 棧模擬遞迴
程式碼
#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;
}