输入十个数进行排序_最快最简单的排序算法--桶排序

微信公众号:小白算法
关注可了解更多算法,并领取免费学习资料。问题或建议,请公众号留言; 文末有资料领取

白话算法(第一回:小白军师)

在我们的生活中,排序无处不在,排队按高矮,工资分高低,淘宝购物时,也有按照价格排序,按照销量排序等等。在讲今天的最快最简单的算法--桶排序之前,我们可以用一个例子来介绍一下排序算法。

6bd7157c1b987d4f497b67ac9ec516be.png

韩信点兵的故事大家都知道,那我们今天以韩信为例,介绍我们的算法。韩信分别给帐中五个将军分兵,按照将军的战场经验的多少,以及当时分工,分别给五个将军分为5个兵团,7个兵团,5个兵团,3个兵团,2个兵团。在攻打城池时,他觉得兵团数最多的应当冲在前面打头阵,少的就做后援。韩信于是请了小白做军师,要求小白我给他安排一下。

45d75fd4662733f2307cb9f1d61b85a0.png

小白得此重任,穿越回二十一世纪,用计算机给韩信大将军做了一下分析。用了一个一维数组解决了这个问题。
首先,小白申请了一个大小为8数组int a[8].于是就有了8个变量,编号就是a[0]~b[7]了。这八个变量初始值刚开始定义为0,初值0就是表示带队兵团个数为0。现在五个将军都有带兵团,不存在不带兵团的光杆将军。

c0819e24beb92f81820d2321b2b6360d.png

下面我们处理每一个将军的带团数,第一个是5个团,于是小白就在a[4]上加上1,表示5出现过一次。

ecb4911595defefd6374af0fd798cfd1.png

第二个将军是7个团,在a[7]的值加上1。表示7出现过一次。

8c9115e28f0d6c761fa7aa421fd27160.png

第三个将军带团5个,在a[4]的值上继续加1。表示5出现了一次,此时a[4]的值就为2了,出现了两次。

0b61ff484114ec82c7f09bbaaa470d42.png

再接着按照此方法处理另外两个将军的兵团。

a1251be1d7a35acd15e641fd2b3ba36a.png

此时,大家应该已经明白a[0]-a[7]中的数值表示的是兵团数出现的次数。接下来我们就将这个顺序打印出来,出现几次就打印几次:
a[0]为0,表示“0”没有出现过,不打印;
a[1]为0,表示“1”没有出现过,不打印;
a[2]为1,表示“2”出现过1次,打印2;
a[3]为1,表示“3”出现过1次,打印3;
a[4]为0,表示“4”没有出现过,不打印;
a[5]为2,表示“5”出现过1次,打印5 5;
a[6]为0,表示“6”没有出现过,不打印;
a[7]为1,表示“7”出现过1次,打印7;
则最终打印出来数据为2 3 5 5 7,完整代码如下:

#include <iostream>
int main()
{
    int a[9],t;
    for (int i=0;i<=8;i++)  //a[7]数组初始化为0
    {
        a[i]=0;
    }
    for (int i=1;i<=5;i++)  //依次输入五个数
    {
        scanf_s("%d",&t);
        a[t]++;
    }
    for (int i=0;i<=8;i++)
    {
        for (int j = 1;j<=a[i];j++)
        {
            if (a[i]!=0)
            {
                printf("%dt",i);
            }

        }
    }
    system("pause");
    return 0;
}

其中依次输入为:
5 3 5 2 7

这个算法就好像8个桶,编号为0~7,此时各个数字每出现一次就在该编号桶里放入一面小旗,最终只要观察每个编号桶里只要有几面旗就行。

d230a1185f49ed5538a6b26f55302c99.png
我们来分析一下这个算法的复杂度,在程序读入数组写入初始值时循环n次,即为n个桶。在输入数据时,循环了m次,即复杂度现在为O(m+n),后面打印的时候又循环了(n+m)次,所以总共复杂度为O(m+n+m+n),复杂度忽略较小的常数,最终桶排序的复杂度为O(m+n),通常用大写字母表示为O(m+n)。

最终按照此排序方法,帮韩信处理好了攻城兵团的顺序。当然最终结局帮韩信取得了战争的胜利,接下来的,胜利总结会议便是要小白帮他们讲解这种快速排序的方法

e7d00a4e08935b3d2f1efb460a0b95f8.png

算法理解(第二回:胜利总结会议)

这里运用到一个很重要的桶排序概念,先叙述一下这个概念,能理解的就理解,不能理解的地方可以参照第一回的战争记录。

桶排序 (Bucket sort)或所谓的箱排序,是一个排序算法,工作的原理是将数组分到有限数量的桶子里。每个桶子再个别排序(有可能再使用别的排序算法或是以递归方式继续使用桶排序进行排序)。桶排序是鸽巢排序的一种归纳结果。当要被排序的数组内的数值是均匀分配的时候,桶排序使用线性时间(Θ(n))。但桶排序并不是 比较排序,他不受到 O(n log n) 下限的影响。

虽然桶排序快又简单,但是实际情况还是很多场景照顾不到,例如,假设我们要求韩信下令时,按照将军名字下令,x将军带领的7个兵团正面攻击咸阳,于是我们就不能像例子中用兵团数出现的次数作为排序依据,应当用人名来作为排序依据。输出应当为,a将军(2个兵团)、b将军(3个兵团)、c将军(5个兵团)、d将军(5个兵团)、e将军(7个兵团)。所以这时要用到我们之前所提到的冒泡排序,解决此类问题。

冒泡排序教程:https://mp.weixin.qq.com/s/wz4aKeKJDW82X3arZfVbpQ

如果只是想对算法进行了解,你就可以选择关注“小白算法”公众号,我们每周都会有新的算法介绍,并有相关学习资料赠送。
本周赠送的书籍为《面向机器智能的TensorFlow实践 (智能系统与技术丛书)》,机器学习的入门教程书籍,关注公众号回复“105”即可获得。

bf313717364d045b86c2bbd0c306779e.png
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值