1. 程式人生 > >快速排序---優化

快速排序---優化

傳送門:洛谷 P1177


吐槽

坑爹的資料,目測有一堆重複的元素。

優化

  1. 對於樞軸的優化:
    三點取中法( l , m i d , r
    l,mid, r
    取三點中間值)
    隨機數法(隨機數)
  2. 對於排序方法優化:
    與其他排序方法混用( E g . Eg. 在範圍較小時直接用插入排序)
    將相同的元素聚集在一起
  3. 棧模擬遞迴

程式碼

#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; }