zoukankan      html  css  js  c++  java
  • 排序5

    基数排序,之所以介绍它,是因为它有一个特点,排序的时间复杂度为O(n)。另外,基数排序是一种特殊的桶排序。

    同样先问一些问题:

    1. 为什么它可以这么快,怎么和之前的不同?
    2. 为什么工程中多使用快排而不是基数排序,它有什么弊端?

    桶排序

    桶排序可以说是最简单最快的排序算法了,思想就是将输入数据放置到不同的桶中,然后在各个桶内再进行递归地排序。桶的数量是不唯一的,最简单的就是设置和值域相同个数的桶,比方说输入的数值范围是0-100,那么就设置101个桶,无论多少个数,都能放到这个桶内,相当简单。

    缺点就是,这样设置的话,桶的个数就变成了与值域大小相关,如果只有两个数1和100000,那就要设置10000个桶,太过占空间。而且如果输入数据分布不均匀,都丢进了相同的桶,那就要继续递归的排序,这样轮数可能增加,效率也会降低。

    桶排序是时间复杂度是O(n)级别,其不属于比较排序,所以不受比较排序的时间复杂度下界的限制。

    具体实现没写过,也不能盗别人的代码,有兴趣的筒子们去网上找一下吧。

    基数排序

    基数排序是一种特殊的桶排序,其桶的个数依赖于数的进制,如十进制就以10为桶的个数。其排序思想和人脑排序很像,一位一位的比较。人脑先看最高位,若相同则看下一位;基数排序从最低位往上一位一位地排序,保证在最高位相同的情况下,较低位置已经有序。

    盗用书上的一张图:

    那把数字分成一位一位本身不就很耗时吗?是的没错,但这个并不会提高排序时间复杂度的量级,只是会增加常数因子。

    如上例所示,基数排序分为分配和收集两个过程,在分配过程中,每次处理一位,就是把该数丢到对应的桶中。对该位处理完毕之后,进入收集环节,按照桶的顺序,也即0-9的顺序将树收集起来。很明显,这样可以保证排序的稳定性。

    基数排序的实现和复杂度

    怎么实现桶? 可以是数组,也可以是链式实现。

    具体代码? 有兴趣的同志可以网上搜一下,应该不是很难。最近心力憔悴,也没写,希望有机会补上吧。

    时间复杂度?

    每一位处理都会遍历整个数集,假设最高位为第m位,那么时间复杂度为O(m+n)。

    空间复杂度?

    无论是数组还是链式,都会申请额外空间,这已经做不到原址排序了,所以它能这么快,也是空间换时间的结果。空间复杂度至少为O(m+n)。

    回答开始的问题

    • 为什么可以这么快?

    这个已经在上一节分析了。

    • 为什么它这么快,我们还用快排?

    其实也是和空间复杂度有关,我猜还是占用内存太多,太麻烦。网上也查了一点资料,有人说,有些输入是没有基的,比如字符串。这个我不赞同,字符串按位比较有问题? 还在书上看到,只适用正整数排序。同样不赞同,正数负数可以分开排序再合并,小数同样可以按位比较,只是稍微麻烦了点。有人说,有些问题必须要比较才能解决。这个我有疑惑,得到排序结果不就是一种比较结果吗?其实我也没有遇到这样的问题,所以也不敢说不赞同,希望以后真的遇到了,再来这里补充一下吧。

    这里我找到了《算法导论》里的一种解释,贴出来,大家参考一下。

    写在排序篇之后

    从第一篇随笔开始,恐怕也写了有半个月了,自知理解和实战能力都不算强,更谈不上拿我的博客来学习。最主要还是想自己作下记录吧,如果真的有感兴趣的小伙伴能坚持看到这里,衷心地感谢你!如果有写的不对的地方,尽管指出来啊。

    知之为知之,不知为不知,存一份实事求是的敬畏之心!

  • 相关阅读:
    easyui 例子2
    easyui 1
    SqlHelper.cs
    ajax 视频点赞功能
    路线
    .net面试题
    cookie 和session asp.net
    前端面试2
    前端面试1
    bootstrap 初始学习篇
  • 原文地址:https://www.cnblogs.com/ustcwx/p/8119762.html
Copyright © 2011-2022 走看看