`

分配排序 桶排序与基数排序

 
阅读更多

基本演化顺序是:分配排序——桶排序——基数排序

分配排序是最基本的为所有可能都分配一个存储位置的方法

桶排序是在分配排序的基础上为相同元素或在同一个范围内的元素分配同一个桶,因此每个桶可以看做一个变长的链表

基数排序是将元素分等级从最次级到最高级不断进行递进的排序过程

 

 

桶排序(在这里与分配排序一致:因为不存在重复元素且不划分范围)

这是迄今为止最快的一种排序法,其时间复杂度仅为Ο(n),也就是线性复杂度!但它是有条件的。

举个例子:一年的全国高考考生人数为500万,分数使用标准分,最低100,最高900,没有小数,你把这500万元素的数组排个序。我们抓住了这么个非常特殊的条件,就能在毫秒级内完成这500万的排序,那就是:最低100,最高900,没有小数,那一共可出现的分数可能有多少种呢?一共有900-100+1=801,那么多种,想想看,有没有什么“投机取巧”的办法?方法就是创建801个“桶”,从头到尾遍历一次数组,对不同的分数给不同的“桶”加料.

比如有个考生考了500分,那么就给500分的那个桶(下标为500-100)加1,完成后遍历一下这个桶数组,按照桶值,填充原数组,100分的有1000人,于是从0填到999,都填1000,101分的有1200人,于是从1000到2019,都填入101.于是经过这次遍历之后所有记录都是有序的了。

很显然,如果分数不是从100到900的整数,而是从0到2亿,那就要分配2亿个桶了,这是不可能的,所以桶排序有其局限性,适合元素值集合并不大的情况。

 

 

在上面的基础上就有了基数排序

基数排序是对桶排序的一种改进,这种改进是让“桶排序”适合于更大的元素值集合的情况,而不是提高性能。

 

我们先看看扑克牌的例子。一张牌有两个关键字组成:花色(桃<心<梅<方)+面值(2<3<4<...<A)。假如一张牌的大小首先被花色决定,同花色的牌有数字决定的话。我们就有两种算法来解决这个问题。

(1) 首先按照花色对所有牌进行稳定排序,这样就可以将所有牌分成4组。然后同组的牌(同花色)再按照面值进行排序。

(2) 首先按照面值对所有牌进行稳定排序,然后按照花色再次对所有牌进行稳定排序。

在这里的第二种方法就是基数排序!————也就是从最次的关键字开始排序,再从第二次的关键字排序,过程中参考第一次排序后元素间的相对顺序,以此类推直到最高关键字参考了次高关键的顺序而排序完成,排序结束。

 

 

比如字符串“abcd” “aesc” "dwsc" "rews"就可以把每个字符看成一个关键字。另外还有整数 425、321、235、432也可以每个位上的数字为一个关键字。

 

基数排序的思想就是将待排数据中的每组关键字依次进行桶分配。比如下面的待排序列:

                 278、109、063、930、589、184、505、269、008、083

我们将每个数值的个位,十位,百位分成三个关键字: 278 -> k1(个位)=8  ,k2(十位)=7 ,k3=(百位)=2。

然后从最低位个位开始(从最次关键字开始),对所有数据的k1关键字进行桶分配(因为,每个数字都是 0-9的,因此桶大小为10),再依次输出桶中的数据得到下面的序列。

       930、063、083、184、505、278、008、109、589、269(从最次关键字开始排序)

再对上面的序列接着进行针对k2的桶分配,输出序列为:

       505、008、109、930、063、269、278、083、184、589(参考最次关键字来排序第二次关键字)

最后针对k3的桶分配,输出序列为:

       008、063、083、109、184、269、278、505、589、930(参考第二次关键字来排序最高关键字)

 

很明显,基数排序的性能比桶排序要略差。每一次关键字的桶分配都需要O(N)的时间复杂度,而且分配之后得到新的关键字序列又需要O(N)的时间复杂度。假如待排数据可以分为d个关键字,则基数排序的时间复杂度将是O(d*2N) ,当然d要远远小于N,因此基本上还是线性级别的。但是,对比桶排序,基数排序每次需要的桶的数量并不多。而且基数排序几乎不需要任何“比较”操作,而桶排序在桶相对较少的情况下,桶内多个数据必须进行基于比较操作的排序。

 

经典排序算法 - 基数排序Radix sort

原理类似桶排序,这里总是需要10个桶,多次使用

首先以个位数的值进行装桶,即个位数为1则放入1号桶,为9则放入9号桶,暂时忽视十位数

例如

待排序数组[62,14,59,88,16]简单点五个数字

分配10个桶,桶编号为0-9,以个位数数字为桶编号依次入桶,变成下边这样

|  0  |  0  | 62 |  0  | 14 |  0  | 16 |  0  |  88 | 59 |

|  0  |  1  |  2  |  3  |  4 |  5  |  6  |  7  |  8  |  9  |桶编号

将桶里的数字顺序取出来,

输出结果:[62,14,16,88,59]

再次入桶,不过这次以十位数的数字为准,进入相应的桶,变成下边这样:

由于前边做了个位数的排序,所以当十位数相等时,个位数字是由小到大的顺序入桶的,就是说,入完桶还是有序

|  0  | 14,16 |  0  |  0  |  0  | 59 | 62  | 0  | 88  |  0  |

|  0  |  1      |  2  |  3  |  4  |  5  |  6  |  7  |  8  |  9  |桶编号

 

因为没有大过100的数字,没有百位数,所以到这排序完毕,顺序取出即可

最后输出结果:[14,16,59,62,88]

 

分享到:
评论

相关推荐

    java算法——基数排序/桶排序

    基数排序/桶排序 *统计将数组中的数字分配到桶中后,各个桶中的数字个数 *数组中每个数的每一位数根据大小分配到对应大小为0~9的桶 *将各个桶中的数字个数,转化成各个桶中最后一个数字的下标索引

    数据结构基数排序数据结构基数排序

    基数排序的核心思想是将数字按照位数从低位到高位分别进行桶排序,最终得到完全有序的序列。下面将详细阐述基数排序的原理、步骤、优缺点以及实际应用。 一、基数排序的原理 基数排序是根据每个数字的每一位来进行...

    基于双向链表的基数排序

    基数排序(radix sort)又称桶排序(bucket sort),相对于常见的比较排序,基数排序是一种分配式排序,需要将关键字拆分成数字位。并且按照数字位的值对数据项进行排序,这种方法不需要进行比较操作。 为了尽可能少的...

    基数排序C语言实现

    基数排序基于“分配”和“收集”的思想,其过程分为两个阶段:分配(分配排序)和收集(归并)。首先,从最低有效位(个位)开始,将所有数字按位值分配到各自的桶中,然后再依次从桶中收集回原数组。这一过程会重复...

    排序算法: 冒泡排序,桶排序,计数排序,堆排序,插入排序,合并排序,快速排序,基数排序,选择排序,希尔排序 实现语言: C

    桶排序是一种分布式排序算法,将元素分配到有限数量的桶里,每个桶再分别排序。适用于元素分布均匀且在一定范围内的场景,最佳情况下的时间复杂度可达到O(n+k),其中k是桶的数量。 3. **计数排序**: 计数排序是...

    基数排序-radix sort

    在排序过程中,使用稳定的排序算法,如计数排序或桶排序,来处理每一位的排序。 ### 2. 基数排序的步骤 - **确定最大数**:在待排序的数组中找出最大数,以确定需要进行多少轮排序。 - **分配阶段**:从最低位开始...

    基数排序课程设计.rar

    桶排序则是将元素分配到多个“桶”中,每个桶再单独排序,最后按照桶的顺序合并所有结果。 在这个课程设计中,你会学习到以下几点: 1. **理解基数排序原理**:掌握基数排序的工作机制,包括位数切割、桶的创建和...

    Radix Sort (基数排序)排序算法

    基数排序的实现主要依赖于桶的概念。在每次循环中,每个元素都会根据当前处理的位数被分配到相应的桶中。下面是具体的实现细节: - **初始化**:创建一个单向队列,将待排序的元素添加到队列中。 - **桶的准备**:...

    Python数据结构与算法之常见的分配排序法示例【桶排序与基数排序】

    ### Python数据结构与算法之常见的分配排序法示例:桶排序与基数排序 在计算机科学领域,排序算法是一项基础而重要的技术,它被广泛应用于多种场景之中,例如数据库管理、搜索算法以及各种需要对数据进行组织的应用...

    数据结构之基数排序数据结构之基数排序数据结构之基数排序

    通常,我们可以使用计数排序、桶排序或分配排序等稳定的排序算法来处理每一位。稳定性的需求来源于多关键字排序时,保证相同关键字的元素保持原有的相对顺序。 基数排序的效率主要取决于数据的位数和每一轮排序的...

    基数排序的原理及应用.pdf

    非比较型排序:与快速排序、归并排序等比较型排序算法不同,基数排序不是通过元素之间的比较来确定它们的顺序,而是通过分配和收集的方式来实现排序。 4. 基数排序的应用 1. 整数排序:基数排序特别适用于整数排序,...

    C经典算法之基数排序法

    **基数排序**是一种典型的非比较性排序算法,它属于分配式排序的一种,其基本思想是将待排序的数据分成不同的组或者桶,然后按照一定的规则对这些组进行排序。基数排序通常适用于整数排序,特别是当整数范围不大但...

    归并排序,基数排序算法比较

    在这个程序中,`Radixsort()`函数实现了基数排序,它通过计算每个位的频率(`count[]`数组),并将数字按照每个位的值分配到对应的桶(`a[][]`数组)中。最后,通过`back()`函数将桶中的数字依次取出,完成排序。...

    基数排序算法

    2. **选择桶**:基数排序的核心在于使用桶。通常会使用10个桶,每个桶代表一个数字(0-9)。 3. **分配**:按照最低有效位(Least Significant Digit, LSD)对数字进行分配。将每个数字放入对应的桶中。例如,如果...

    基数排序算法 java实现

    基数排序的基本思想是通过创建多个桶来分配和收集元素。每个桶对应一个特定的数值范围,这些桶按照数值的位数进行,从最低位到最高位。在排序过程中,我们先按最低位对所有元素进行排序,然后按次低位,直到最高位。...

    基数排序基数排序基数排序

    基数排序是一种非比较型整数排序算法,它的原理是将整数按位数切割成不同的数字,然后按每个位数分别比较。这种排序方法不需要进行记录关键字间的比较,而是通过“分配”和“收集”操作对单逻辑关键字进行排序。 1....

    基数排序_C语言_源码_数据结构

    通过循环遍历每个位,使用计数排序(counting sort)或者桶排序(bucket sort)策略。 - 关键步骤包括: - 确定最大数,用于确定需要进行几轮排序。 - 初始化桶,每个桶对应0-9的一个数字。 - 从低位开始,对每...

    用stl实现基数排序算法

    2. **分配桶**:基数排序的核心思想是将数字分到桶里,每个桶代表一个特定的位值。例如,对于十进制数,可以创建10个桶,分别对应0-9的每一位。可以使用STL的`std::vector`来创建这些桶。 3. **分配数字**:遍历...

    基数排序_RADIXSORT

    在基数排序中,我们可以将每个数字分配到对应的“桶”里,这里的“桶”代表的是每一位的数值范围。例如,对于十进制数,0-9的每个数字对应一个桶。然后,我们依次处理每个位,将数字从低到高移动到正确的桶,直到...

    C# 插入排序 冒泡排序 选择排序 快速排序 堆排序 归并排序 基数排序 希尔排序

    从低位到高位,对每个位数进行一次分配排序,如桶排序。 - C# 实现基数排序时,需要创建多个桶,按位进行分配和收集,适用于处理整数排序。 8. **希尔排序**(Shell Sort): - 希尔排序是插入排序的改进版,通过...

Global site tag (gtag.js) - Google Analytics