基数排序详解以及java实现

前言基数排序(radix sort)又称桶排序(bucket sort),相对于常见的比较排序,基数排序是一种分配式排序,即通过将所有数字分配到应在的位置最后再覆盖到原数组完成排序的过程。我在上一篇讲到的计数排序也属于这种排序模式,上一篇结尾处提到了计数排序的稳定性,即排序前和排序后相同的数字相对位置保持不变。今天我们要说的基数排序就要利用到排序稳定性这一点。思考过程 我们回想...
摘要由CSDN通过智能技术生成

前言

基数排序(radix sort)又称桶排序(bucket sort),相对于常见的比较排序,基数排序是一种分配式排序,即通过将所有数字分配到应在的位置最后再覆盖到原数组完成排序的过程。我在上一篇讲到的计数排序也属于这种排序模式,上一篇结尾处提到了计数排序的稳定性,即排序前和排序后相同的数字相对位置保持不变。今天我们要说的基数排序就要利用到排序稳定性这一点。

思考过程

     我们回想一下我们小时候是怎么学习比较数字大小的?我们是先比位数,如果一个位数比另一个位数多,那这个数肯定更大。如果位数同样多,就按位数递减依次往下进行比较,哪个数在这一位上更大那就停止比较,得出这个在这个位上数更大的数字整体更大的结论。当然我们也可以从最小的位开始比较,这其实就对应了基数排序里的MSD(most significant digital)和LSD(least significant digital)两种排序方式。

     想清楚了这一点之后,我们就要考虑如何存储每一位排序结果的问题了,首先既然作为分配式排序,联想计数排序,每一位排序时存储该次排序结果的数据结构应该至少是一个长度为10的数组(对应十进制该位0-9的数字)。同时可能存在以下情况:原数组中所有元素在该位上的数字都相同,那一维数组就没法满足我们的需要了,我们需要一个10*n(n为数组长度)的二维数组来存储每次位排序结果。熟悉计数排序结果的读者可能会好奇:为什么不能像计数排序一样,在每个位置只存储出现该数字的次数,而不存储具体的值,这样不就可以用一维数组了?这个我们不妨先思考一下,在对基数排序分析完之后再来看这个问题。

      现在我们可以存储每次位排序的结果了,为了在下一位排序前用到这一位排序的结果,我们要将桶里排序的结果还原到原数组中去,然后继续对更改后的原数组执行前一步的位排序操作,如此循环,最后的结果就是数组内元素先按最高位排序,最高位相同的依次按下一位排序,依次递推。得到排序的结果数组。

 

算法过程

  1. 初始化:构造一个10*n的二维数组,一个长度为n的数组用于存储每次位排序时每个桶子里有多少个元素。
  2. 循环操作:从低位开始(我们采用LSD的方式),将所有元素对应该位的数字存到相应的桶子里去(对应二维数组的那一列)。然后将所有桶子里的元素按照桶子标号从小到大取出,对于同一个桶子里的元素,先放进去的先取出,后放进去的后取出(保证排序稳定性)。这样原数组就按该位排序完毕了,继续下一位操作,直到最高位排序完成。

下面给出一个实例帮助理解:

我们现有一个数组:73, 22, 93, 43, 55, 14, 28, 65, 39, 81

下面是排序过程(二维数组里每一列对应一个桶,因为桶空间没用完,因此没有将二维数组画全):

1.按个位排序

<

0

1

2

3

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值