快速排序---优化

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_27121257/article/details/82744497

传送门:洛谷 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;
}

猜你喜欢

转载自blog.csdn.net/qq_27121257/article/details/82744497