线性时间排序之计数排序,基数排序和桶排序

前面几篇文章已经介绍了几种能在O(nlgn)时间内排序n个数的算法,归并排序和堆排序达到了最坏情况下的上界(渐进最优); 快排在平均情况下达到下界; 但是这些算法都有一点:在排序的最终结果中,各元素的次序依赖与它们之间的比较, 所以称为比较排序, 这一篇介绍三种线性时间复杂度的算法,排序不依赖与比较:计数排序,基数排序和桶排序

计数排序
假设n个输入元素中每个都是在0-k这个区间的, k 是一个整数。当k = O(n)时,运行时间为Θ(n);

基本思对想:对每一个输入元素x,确定小于x的元素个数,就可以直接把元素放在该放的位置上
伪代码:

//输入是数组A, 数组B存放排序的输出,C提供临时空间,计数位置
CountingSort(int A[],int B[],int k)
{
    int *C = new int[k+1];
    for(int i = 0;i<=k;i++)
    C[i] = 0;
    for(int j= 1;j<=A.length;j++)
    C[A[j]] = C[A[j]]+1;//数每个A[j]的个数
    for(int i = 1;i<=k;i++)
    C[i] = C[i]+C[i-1];//计算每个数前面比其小的有多少
    for(int j = A.length;j>=1;j--)
    {
        B[C[A[j]]] = A[j];
        C[A[j]] --;
    }
}

线性时间排序之计数排序,基数排序和桶排序_第1张图片

基数排序

从低位到高位排
先按个位数收集成一组,在次基础上按高一位收集成一组,依次进行,最后成为有序数组
线性时间排序之计数排序,基数排序和桶排序_第2张图片
线性时间排序之计数排序,基数排序和桶排序_第3张图片
线性时间排序之计数排序,基数排序和桶排序_第4张图片

桶排序
假设输入数据服从均匀分布,平均情况下时间代价为O(n)。桶排序假设输入是由一个随机过程产生,该过程将元素均匀独立的分布在[0,1)区间
先将该区间划分为n个相同大小的子区间,或称为桶,然后将各个数放到对应桶中,先对每个桶中数进行排序,然后遍历桶

BucketSort(A)
{
    n = A.length;
    int *B = new int[n];
    for(int i = 0;i<=n-1;i++)
    {
    make B[i] an empty list;
    }
    for(int i = 1;i<=n;i++)
    insertA[i] into listB[nA[i]];
    for(int i = 0;i<=n-1;i++)
    sort list B[i] 
    concentrste the lists B[0],B[1]...B[n-1]together in order
}

你可能感兴趣的:(算法)