zoukankan      html  css  js  c++  java
  • 桶排序(Bucket Sort)

    标签

    稳定排序、非原地排序、非比较排序

    基本思想

    桶排序也是分配排序的一种,但其是基于比较排序的,这也是与基数排序最大的区别所在。

    桶排序也是计数排序的升级版。它利用了函数的映射关系,高效与否的关键就在于这个映射函数的确定。

    桶排序算法想法类似于散列表。首先要假设待排序的元素输入符合某种均匀分布,例如数据均匀分布在[ 0,1)区间上,则可将此区间划分为10个小区间,称为桶,对散布到同一个桶中的元素再排序(可使用别的排序算法或是以递归方式继续)。

    要求:待排序数长度一致。

    基数排序 vs 计数排序 vs 桶排序

    这三种排序算法都利用了桶的概念,但对桶的使用方法上有明显差异:

    • 基数排序: 根据键值的每位数字来分配桶。
    • 计数排序: 每个桶只存储单一键值。
    • 桶排序: 每个桶存储一定范围的数值。

    算法描述

      • 步骤1:人为设置一个BucketSize,作为每个桶所能放置多少个不同数值(例如当BucketSize==5时,该桶可以存放{1,2,3,4,5}这几种数字,但是容量不限,即可以存放100个3);
      • 步骤2:遍历输入数据,并且把数据一个一个放到对应的桶里去;
      • 步骤3:对每个不是空的桶进行排序,可以使用其它排序方法,也可以递归使用桶排序;
      • 步骤4:从不是空的桶里把排好序的数据拼接起来。 

        注意,如果递归使用桶排序为各个桶排序,则当桶数量为1时要手动减小BucketSize增加下一循环桶的数量,否则会陷入死循环,导致内存溢出。

    动图演示

    时间复杂度

    对$n$个关键字进行桶排序的时间复杂度分为两个部分: 
    (1) 循环计算每个关键字的桶映射函数,这个时间复杂度是O(n)。

    (2) 利用先进的比较排序算法对每个桶内的所有数据进行排序,对于n个待排数据,m个桶,平均每个桶[n / m]个数据,则桶内排序的时间复杂度为$sum{i = 1}^{m} O(n_i ∗ log n_i) = O(n * log nm)$。其中$n_i$为第$i$个桶的数据量。

    因此,桶排序的时间复杂度,取决与对各个桶之间数据进行排序的时间复杂度,因为其它部分的时间复杂度都为$O(n)$。很显然,桶划分的越小,各个桶之间的数据越少,排序所用的时间也会越少。但相应的空间消耗就会增大。平均时间复杂度为线性的$O(n + k)$,$k$为桶内排序所花费的时间。当每个桶只有一个数,则最好的时间复杂度为:$O(n)$。

    最好情况:$O(n)$

    最坏情况:$O(n + k)$

    平均情况:$O(n + k)$

    空间复杂度

    额外的空间开销为桶的个数 * 每个桶所占内存空间。

    算法示例

    参考资料:

    https://blog.csdn.net/coolwriter/article/details/78732728

    https://blog.csdn.net/weixin_41190227/article/details/86600821

    https://www.cnblogs.com/itsharehome/p/11058010.html

    Min是清明的茗
  • 相关阅读:
    Python(93)_网络编程基础
    Web前端(13)_路径
    Web前端(12)_注释
    Web前端(11)_base标签
    Python(91)_python复习
    Web前端(10)_css文本样式
    Web前端(9)_div+span等标签
    虚拟化(6)_CPU虚拟化
    虚拟化(5)_打开tcp监听
    虚拟化(4)_离线克隆与在线克隆
  • 原文地址:https://www.cnblogs.com/MinPage/p/13963659.html
Copyright © 2011-2022 走看看