有趣的桶排序

程序员的核心技能之一就是算法,谈到算法,似乎都是从排序开始。对一组已知范围的数据进行排序,最快的算法是什么呢?快速排序?希尔排序?非也,非也~是本文的主角“桶排序”!
  来看一个实际例子吧:已知一组范围在0~10的数据(如:9,5,2,7,7),你有没有什么好方法编写一段程序,将数据从大到小输出呢?
  看到这样的题目,相信很多人第一反应跟我一样,就是将这些数据进行比较,然后进行位置的交换,最终实现排序。可桶排序彻底颠覆了这种想法——第一次看到桶排序时,确实被惊艳到了——还有这种操作?!原来排序不一定非得老老实实对原有数据进行位置调整!
  好了,回到我们的题目。我们只需要借助一个一维数组就可以解决问题。首先,我们申请一个长度为11的数组int a[11],因为我们的数据范围是0~10,而int a[11]的元素正好是a[0]~a[10]。开始的时候,我们将所有元素都初始化为0,表示这些数都未出现过。例如a[0]等于0,就表示待排序数据还未出现过0;同理,若a[9]等于1,则表示待排数据中9出现过1次。
  有了上面的说明,那接下来就非常简单了,我们只需要遍历待排数组,然后将每个数值对应下标的元素加1(比如第一个数是9,我们就将a[9]加1)。你会发现,待排数组遍历完之后,a[0]~a[10]中的数值,其实就是0~10出现的次数,我们只需要按次数将下标打印出来就实现排序了。代码如下:

#include <stdio.h>
int main()
{
    int a[11],i,j,t;
    for(i=10; i>=0; i--)
    {
        a[i]=0;
    }

    for(i=1; i<=5; i++) //循环读入5个待排数
    {
        scanf("%d",&t); //把每一个数读到变量t中
        a[t]++; //进行计数
    }

    for(i=10; i>=0; i--)
    {
        for(j=1; j<=a[i];j++)
        {
            printf("%d ",i);
        }
    }

    printf("\r\n"); 
    getchar();  
    return 0;
}

执行该程序,我们可以随意输入5个0~10的数字,然后程序会将其按从大到小排序输出,如下图:

图1

  接下来我们来看看时间复杂度。首先我们用了一个m次(m为桶的个数)的循环把桶清空;然后再用一个n次(n为待排序数据的个数)的循环,设置的数据的显示次数;最后又进行了m+n次循环,把数据显示出来。所以,整个排序算法一共执行了m+n+m+n次。我们用大写字母O来表示时间复杂度,因此该算法的时间复杂度是O(m+n+m+n)即O(2*(m+n))。我们在说时间复杂度的时候可以忽略较小的常数,最终桶排序的时间复杂度为O(m+n)。还有一点,在表示时间复杂度的时候,n和m通常用大写字母即O(M+N),这是一个非常快的排序算法。
  桶排序虽快,但其实它是用空间在换时间。如果需要排序的数范围非常宽,那我们就需要申请非常多的“桶”来存储每一个数出现的次数。即使依然只是需要对5个数进行排序,这太浪费空间了!所以在选择使用哪种排序算法之前,还是需要根据实际情况,权衡好复杂度与空间的问题。

参考书籍:《啊哈!算法》
说明:本文所提到的是简化版的桶排序算法,真正的同排序算法要复杂些,有兴趣的朋友可以自行搜索学习。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 135,810评论 19 139
  • 数据结构与算法——计数排序、桶排序、基数排序 计数排序 计数排序有如下四个步骤。 首先会对每个输入进行频率统计,得...
    sunhaiyu阅读 4,853评论 0 11
  • 某次二面时,面试官问起Js排序问题,吾绞尽脑汁回答了几种,深感算法有很大的问题,所以总计一下! 排序算法说明 (1...
    流浪的先知阅读 4,919评论 0 4
  • 概述:排序有内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部...
    每天刷两次牙阅读 9,091评论 0 15
  • 一场放逐心灵的救赎 静下心来认认真真地写份东西,还是很珍惜这种踏实安心的感觉。 《肖申克的救赎》(《TheShaw...
    Mon阿修阅读 2,720评论 0 1

友情链接更多精彩内容