数据结构和算法

排序算法下——桶排序、计数排序和基数排序

2018-10-20  本文已影响12人  seniusen

桶排序、计数排序和基数排序这三种算法的时间复杂度都为 O(n),因此,它们也被叫作线性排序(Linear Sort)。之所以能做到线性,是因为这三个算法是非基于比较的排序算法,都不涉及元素之间的比较操作。

1. 桶排序(Bucket Sort)?

1.1. 桶排序原理

桶排序

1.2. 桶排序的时间复杂度分析

1.3. 桶排序的适用条件

桶排序看起来很优秀,但事实上,桶排序对排序数据的要求是非常苛刻的。

1.4. 一个桶排序的实例

假如我们有 10 GB 的订单数据需要按照金额进行排序,但内存只有几百 MB ,这时候该怎么办呢?


2. 计数排序(Counting Sort)?

2.1. 计数排序算法实现

但这个排序算法为什么叫计数排序呢,这是由计数排序算法的实现方法来决定的,我们来看一个简单的例子。

R[8] C[6] 计数排序
// 假设数组中存储的都是非负整数
void Counting_Sort(int data[], int n)
{
    if (n <= 1)
    {
        return;
    }

    // 寻找数组的最大值
    int max = data[0];
    for (int i = 1; i < n; i++)
    {
        if (data[i] > max)
        {
            max = data[i];
        }
    }

    // 定义一个计数数组, 统计每个元素的个数
    int c[max+1] = {0};
    for (int i = 0; i < n; i++)
    {
        c[data[i]]++;
    }

    // 对计数数组累计求和
    for (int i = 1; i <= max; i++)
    {
        c[i] = c[i] + c[i-1];
    }

    // 临时存放排好序的数据
    int r[n] = {0};
    // 倒序遍历数组,将元素放入正确的位置
    for (int i = n-1; i >= 0; i--)
    {
        r[c[data[i]] - 1] = data[i];
        c[data[i]]--;
    }

    for (int i = 0; i < n; i++)
    {
        data[i] = r[i];
    }

}

2.2. 计数排序的适用范围


3. 基数排序(Radix Sort)?

假设要对 10 万个手机号码进行排序,显然桶排序和计数排序都不太适合,那怎样才能做到时间复杂度为 O(n) 呢?

1.1. 基数排序原理

基数排序

参考资料-极客时间专栏《数据结构与算法之美》

获取更多精彩,请关注「seniusen」!


seniusen
上一篇 下一篇

猜你喜欢

热点阅读