ACM模板——排序 - 快速排序(三数取中 + 插排 + 聚集相等元素)

简介: ACM模板——排序 - 快速排序(三数取中 + 插排 + 聚集相等元素)
#include<bits/stdc++.h>
#include<cmath>
#define mem(a,b) memset(a,b,sizeof a);
using namespace std;
typedef long long ll;
const int maxn=3e6+100;
int arr[maxn];
/* 直接插入排序 */
void InsertSort(int low,int high)
{
    int i,j;
    for(i=low+1;i<=high;i++)
    {
        if(arr[i]<arr[i-1])
        {
            arr[0]=arr[i];
            arr[i]=arr[i-1];
            for(j=i-2;arr[0]<arr[j];j--)
                arr[j+1]=arr[j];
            arr[j+1]=arr[0];
        }
    }
}
/* 取待排序序列中low、mid、high三个位置上数据,选取他们中间的那个数据作为枢轴 */
int SelectPivotMedianOfThree(int low,int high)
{
    int mid=low+((high-low)>>1); // >> 优先级低于 + -
    if(arr[mid]>arr[high]) swap(arr[mid],arr[high]);
    if(arr[low]>arr[high]) swap(arr[low],arr[high]);
    if(arr[mid]>arr[low]) swap(arr[mid],arr[low]);
    return arr[low]; // low的位置上保存这三个位置中间的值
}
/* 快排 */
void QSort(int low,int high)
{
    int first,last,left,right,llen,rlen;
    first=left=low, last=right=high, llen=rlen=0;
    if(high-low+1<=10)
    {
        InsertSort(low,high);
        return;
    }
    int key=SelectPivotMedianOfThree(low,high);
    while(low<high)
    {
        while(high>low && arr[high]>=key)
        {
            if(arr[high]==key)
            {
                swap(arr[right],arr[high]);
                right--, rlen++;
            }
            high--;
        }
        arr[low]=arr[high];
        while(high>low && arr[low]<=key)
        {
            if(arr[low]==key)
            {
                swap(arr[left],arr[low]);
                left++, llen++;
            }
            low++;
        }
        arr[high]=arr[low];
    }
    arr[low]=key;
    // 一次快排结束,把与枢轴 key 相同的元素移到枢轴最终位置周围
    int i=low-1, j=first;
    while(j<left && arr[i]!=key)
    {
        swap(arr[i],arr[j]);
        i--, j++;
    }
    i=low+1, j=last;
    while(j>right && arr[i]!=key)
    {
        swap(arr[i],arr[j]);
        i++, j--;
    }
    QSort(first,low-1-llen);
    QSort(low+1+rlen,last);
}
int main()
{
    int n; scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%d",&arr[i]);
    QSort(1,n);
    for(int i=1;i<=n;i++)
    {
        if(i==1)
            printf("%d",arr[i]);
        else
            printf(" %d",arr[i]);
    }
    puts("");
    return 0;
}

image.png


Ps1:三数取中+插排+聚集相等元素,它和STL中的Sort函数效率差不多。

Ps2:尾递归:测试数据分析,其实这种优化编译器会自己优化,相比不使用优化的方法,时间几乎没有减少。


image.png

目录
相关文章
|
4月前
|
搜索推荐 算法
十大排序算法-快排-希尔-堆排-归并-冒泡-桶排-选择-插入-计数-基数
十大排序算法-快排-希尔-堆排-归并-冒泡-桶排-选择-插入-计数-基数
十大排序算法-快排-希尔-堆排-归并-冒泡-桶排-选择-插入-计数-基数
|
6月前
|
机器学习/深度学习 搜索推荐
【七大排序】最基础的排序——冒泡排序
【七大排序】最基础的排序——冒泡排序
38 4
|
7月前
|
机器学习/深度学习 移动开发
【归并排序】【图论】【动态规划】【 深度游戏搜索】1569将子数组重新排序得到同一个二叉搜索树的方案数
【归并排序】【图论】【动态规划】【 深度游戏搜索】1569将子数组重新排序得到同一个二叉搜索树的方案数
|
7月前
|
搜索推荐
排序——交换排序
排序——交换排序
54 0
|
算法
排序篇(三)----交换排序
排序篇(三)----交换排序
48 0
|
机器学习/深度学习 人工智能 搜索推荐
P1177 【模板】快速排序(二分排序)
P1177 【模板】快速排序(二分排序)
84 0
|
机器学习/深度学习 算法 搜索推荐
【八大排序之插入和选择排序】
【八大排序之插入和选择排序】
97 0
|
算法
排序(3)之交换排序
今天小编给大家带来交换排序的内容,对于交换排序中的快速排序在理解上会相对困难一点,小编这里会配合图片给大家细细讲解。那么现在就开始我们今天的主题。
84 0
|
算法
数据结构与算法(六)排序 插入&希尔&归并
数据结构与算法(六)排序 插入&希尔&归并
107 0
ACM模板——排序 - 归并排序
ACM模板——排序 - 归并排序
114 0
ACM模板——排序 - 归并排序