线性时间排序算法

一般我们使用的堆排序,归并排序都是属于比较排序,也就是通过比较元素的大小来进行排序,可以通过决策树分析出比较排序的时间下界是O(nlgn),堆排序和归并排序都是渐进最优的比较排序算法。还有其他的排序方法不是通过比较,下面总结一下:

一:计数排序

大致思路是将数组中所有元素对应小于这个元素的个数存储起来,这样我们可以直接知道这个元素的位置,因为可能出现相同的元素,所以我们从后面输出(为了稳定性)而且每次找到一个元素的位置后要把对应的小于x的个数减一,这样再次输出时就被会放到前一个位置上。最后的时间很好是O(n),但是要开三个数组,而且其中一个数组要开从0到所有比较的数中最大的数,所以是典型的空间换时间,如果比较的元素中有一些非常大就没有办法进行排序。
#include<iostream>

#include<algorithm>

using namespace std;



const int maxnum = 0xffff;

const int maxsize = 0xff;

int length;



void CounterSort(int a[], int b[], const int k)

{

    int c[maxnum];

    int i;

    for (i = 0; i <= k; i++)

        c[i] = 0;

    for (i = 1; i <= length; i++)//统计a中不同的数分别出现的个数

        c[a[i]]++;

    for (i = 1; i <= k; i++)    //c[i]现在代表有几个数小于或等于i

        c[i] = c[i] + c[i - 1];

    for (i = length; i >= 1; i--)

    {

        b[c[a[i]]] = a[i];

        c[a[i]]--;          //对相同元素的个数减一

    }

}



int main()

{

    int a[maxsize], b[maxsize];

    cin >> length;

    int max = -1;

    for (int i = 1; i <= length; i++)

    {

        cin >> a[i];

        if (max < a[i])

            max = a[i];

    }

    CounterSort(a, b, max);

    for (int i = 1; i <= length; i++)

        cout << b[i] << " ";

    cout << endl;

    return 0;

}

:基数排序

大致思路是对于一个位数有限的数,假设位数最高为d,此时从最低位开始排序到最高位就可以完成排序,由于每一位是0-9的数字我们可以在O(n)的时间内完成排序,因此总体的时间复杂度为O(n)。

三、桶排序(Bucket Sort)

桶排序(Bucket Sort)的思想是将数组分到有限数量的桶子里。每个桶子再个别排序(有可能再使用别的排序算法),由于每个桶里面的元素比较少,只需要有限次的操作。当要被排序的数组内的数值是均匀分配的时候,桶排序可以以线性时间运行。桶排序过程动画演示:Bucket Sort,桶排序原理图如下:





猜你喜欢

转载自blog.csdn.net/zwz2011303359/article/details/80875656