线性时间排序

1.计数排序

基本思想:对于每一个输入元素x,确定小于(或等于)x的元素个数,就可以确定x的存放位置.

特点:稳定排序

#include<iostream>
#include<vector>
using namespace std;

void count_sort(vector<int> A,vector<int> &B,int k){
    vector<int> C(k+1,0);
    for(int j=0;j<A.size();j++){
        C[A[j]] = C[A[j]]+1;//或C[A[j]]++;C[i]包含了等于i的元素的个数
    }
    for(int i=1;i<=k;i++){
        C[i] = C[i] +C[i-1];//C[i]包含了不大于i的元素的个数
    }
    for(int j=A.size()-1;j>=0;j--){
        B[C[A[j]]-1] = A[j];//C[A[j]]描述的是位置,下标应该再-1
        C[A[j]] = C[A[j]] -1;
    }
}

int main(){
    vector<int> A{9,2,4,3,5,6,8,7,1,9,6};
    vector<int> B(A.size(),0);
    count_sort(A,B,9);
    for(const auto &c:B){
        cout<<c<<",";
    }
    cout<<endl;
    return 0;
}

2.基数排序

基本思路:采用稳定排序算法从低位到高位对数据的每一位进行排序.

#include<iostream>
#include<vector>
using namespace std;

void count_sort(vector<int> &a,int i,int k){//i表示数据的第i位,k表示每位的最大值
    vector<int> b(a.size(),0);//保存排序后的a
    vector<int> c(k+1,0);
    vector<int> d(a.size(),0);//保存每个元素的第i位
    for(int j=0;j<a.size();j++){
        int r=a[j];
        int x=i;//不能改变i的值
        while(x>0){
            d[j] = r%10;
            r = r/10;
            --x;
        }
    }
    for(int j=0;j<a.size();j++){
        c[d[j]]++;//利用d而不是a来计算c
    }
    for(int i=1;i<=k;i++){
        c[i] = c[i]+c[i-1];
    }
    for(int j=a.size()-1;j>=0;j--){
        b[c[d[j]]-1] = a[j];//保存a[j]而不是d[j]
        c[d[j]] =c[d[j]] -1;
    }
    a=b;
}

void radix_sort(vector<int> &a,int d){
    for(int i=1;i<=d;i++){
        count_sort(a,i,9);
    }
}

int main(){
    vector<int> a{329,457,657,839,436,720,355,97};
    radix_sort(a,3);
    for(const auto &c:a){
        cout<<c<<",";
    }
    cout<<endl;
    return 0;
}

3.桶排序

计数排序假设数据都属于一个小区间内的整数,而桶排序假设输入是由一个随机过程产生,该过程将元素均匀独立地分布在[0,1)区间上.桶排序将[0,1)区间划分为n个大小相同的子区间,即桶.然后将n个输入分别放入各个桶中.先对每个桶中的元素排序,然后依次遍历每个桶,即可得到有序序列.

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;

void bucket_sort(vector<double> a){
    int n = a.size();
    vector<double> b[n];
    for(int i=0;i<n;i++){
        b[static_cast<int>(n*a[i])].push_back(a[i]);//将元素放入桶中
    }
    for(int i=0;i<n;i++){
        sort(b[i].begin(),b[i].end());//对每个桶中的元素排序
    }
    for(const auto &x:b){
        for(const auto &y:x){
            cout<<y<<",";
        }
    }
    cout<<endl;
}

int main(int argc, char const *argv[])
{
    vector<double> a{0.78,0.17,0.39,0.26,0.72,0.94,0.21,0.12,0.23,0.68};
    bucket_sort(a);
    return 0;
}

线性排序算法使用最重要的是,充分利用数据特殊的性质,以达到最佳效果。(source)

原文地址:https://www.cnblogs.com/bukekangli/p/4347914.html