侯体宗的博客
  • 首页
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

PHP排序算法之基数排序(Radix Sort)实例详解

php  /  管理员 发布于 7年前   398

本文实例讲述了PHP排序算法之基数排序(Radix Sort)。分享给大家供大家参考,具体如下:

基数排序在《大话数据结构》中并未讲到,但是为了凑齐八大排序算法,我自己通过网络学习了这个排序算法,并给大家分享出来。

基本思想:

基数排序(radix sort)属于“分配式排序”(distribution sort),又称“桶子法”(bucket sort)或bin sort,顾名思义,它是透过键值的部份资讯,将要排序的元素分配至某些“桶”中,藉以达到排序的作用,基数排序法是属于稳定性的排序,其时间复杂度为O (nlog(r)m),其中r为所采取的基数,而m为堆数,在某些时候,基数排序法的效率高于其它的稳定性排序法。

其实这个思想我也没法总结出来,下面通过例子来说明吧:

基本解法:

PS:在这里我们介绍的基数排序我们采用 LSD(最低位优先),当然还有 MSD(最高位优先),大家自己去百度一下他们之间的异同吧。

假如现在我们有以下这么一些数:

2 343 342 1 128 43 4249 814 687 654 3

我们使用基数排序将他们从小到大排序。

第一步、首先根据个位数的数值,在走访数值(从前到后走访,后面步骤相同)时将它们分配至编号0到9的桶子中:

0 :
1 : 1
2 : 2 342
3 : 343 43 3
4 : 814 654
5 :
6 :
7 : 687
8 : 128
9 : 4249

第二步、接下来将这些桶子中的数值重新串接起来,成为以下的数列:

1 2 342 343 43 3 814 654 687 128 4249

第三步、根据十位数的数值,在走访数值(从前到后走访,后面步骤相同)时将它们分配至编号0到9的桶子中:

0 : 1 2 3
1 : 814
2 : 128
3 :
4 : 342 343 43 4249
5 : 654
6 :
7 :
8 : 687
9 :

第四步、接下来将这些桶子中的数值重新串接起来,成为以下的数列:

1 2 3 814 128 342 343 43 4249 654 687

第五步、根据百位数的数值,在走访数值(从前到后走访,后面步骤相同)时将它们分配至编号0到9的桶子中:

0 : 1 2 3 43
1 : 128
2 : 4249
3 : 342 343
4 :
5 :
6 : 654 687
7 :
8 : 814
9 :

第六步、接下来将这些桶子中的数值重新串接起来,成为以下的数列:

1 2 3 43 128 4249 342 343 654 687 814

。。。。。。后面的步骤大家应该都会走了吧。其实到了第六步的时候就剩 4249 没有排好序了。

从上面的步骤来看,很多的步骤都是相同的,因此肯定是个循环了,我们只需要控制个位、十位、百位、、、、就好了。

还是看代码吧。

算法实现:

//交换函数function swap(array &$arr,$a,$b){  $temp = $arr[$a];  $arr[$a] = $arr[$b];  $arr[$b] = $temp;}//获取数组中的最大数//就像上面的例子一样,我们最终是否停止算法不过就是看数组中的最大值:4249,它的位数就是循环的次数function getMax(array $arr){  $max = 0;  $length = count($arr);  for($i = 0;$i < $length;$i ++){    if($max < $arr[$i]){      $max = $arr[$i];    }  }  return $max;}//获取最大数的位数,最大值的位数就是我们分配桶的次数function getLoopTimes($maxNum){  $count = 1;  $temp = floor($maxNum / 10);  while($temp != 0){    $count ++;    $temp = floor($temp / 10);  }  return $count;}/** * @param array $arr 待排序数组 * @param $loop 第几次循环标识 * 该函数只是完成某一位(个位或十位)上的桶排序 */function R_Sort(array &$arr,$loop){  //桶数组,在强类型语言中,这个数组应该声明为[10][count($arr)]  //第一维是 0-9 十个数  //第二维这样定义是因为有可能待排序的数组中的所有数的某一位上的只是一样的,这样就全挤在一个桶里面了  $tempArr = array();  $count = count($arr);  //初始化$tempArr数组  for($i = 0;$i < 10;$i ++){    $tempArr[$i] = array();  }  //求桶的index的除数  //如798个位桶index=(798/1)%10=8  //十位桶index=(798/10)%10=9  //百位桶index=(798/100)%10=7  //$tempNum为上式中的1、10、100  $tempNum = (int)pow(10, $loop - 1);  for($i = 0;$i < $count;$i ++){    //求出某位上的数字    $row_index = ($arr[$i] / $tempNum) % 10;    for($j = 0;$j < $count;$j ++){      if(@$tempArr[$row_index][$j] == NULL){        $tempArr[$row_index][$j] = $arr[$i];   //入桶        break;      }    }  }  //还原回原数组中  $k = 0;  for($i = 0;$i < 10;$i ++){    for($j = 0;$j < $count;$j ++){      if(@$tempArr[$i][$j] != NULL){        $arr[$k ++] = $tempArr[$i][$j];  //出桶        $tempArr[$i][$j] = NULL;  //避免下次循环的时候污染数据      }    }  }}//最终调用的主函数function RadixSort(array &$arr){  $max = getMax($arr);  $loop = getLoopTimes($max);  //对每一位进行桶分配(1 表示个位,$loop 表示最高位)  for($i = 1;$i <= $loop;$i ++){    R_Sort($arr,$i);  }}

调用算法:

$arr = array(2, 343, 342, 1, 128, 43, 4249, 814, 687, 654, 3);RadixSort($arr);var_dump($arr);

运行结果:

array(11) { [0]=> int(1) [1]=> int(2) [2]=> int(3) [3]=> int(43) [4]=> int(128) [5]=> int(342) [6]=> int(343) [7]=> int(654) [8]=> int(687) [9]=> int(814) [10]=> int(4249)}

其实这些代码我是在挺早之前写的,今天在写博客的时候发现,其实桶就是一个队列,所以上面的 R_Sort()函数复杂了,我们使用 array_push() 和 array_shift() 来重写该方法(当然,要模拟队列的话,用 SPL 提供的 splqueue 是最为恰当的,在这里为了简便我就不用了):

function R_Sort(array &$arr,$loop){  $tempArr = array();  $count = count($arr);  for($i = 0;$i < 10;$i ++){    $tempArr[$i] = array();  }  //求桶的index的除数  //如798个位桶index=(798/1)%10=8  //十位桶index=(798/10)%10=9  //百位桶index=(798/100)%10=7  //$tempNum为上式中的1、10、100  $tempNum = (int)pow(10, $loop - 1);  for($i = 0;$i < $count;$i ++){    //求出某位上的数字    $row_index = ($arr[$i] / $tempNum) % 10;    //入桶    array_push($tempArr[$row_index],$arr[$i]);  }  //还原回原数组中  $k = 0;  for($i = 0;$i < 10;$i ++){    //出桶    while(count($tempArr[$i]) > 0){      $arr[$k ++] = array_shift($tempArr[$i]);    }  }}

基数排序法是属于稳定性的排序,其时间复杂度为O (nlog(r)m),其中r为所采取的基数,而m为堆数。

好了,到这里基数排序就已经给大家介绍完了。这个算法的总结主要是通过看网上的资料,所以就不再给出原作者了。

PS:这里再为大家推荐一款关于排序的演示工具供大家参考:

在线动画演示插入/选择/冒泡/归并/希尔/快速排序算法过程工具:
http://tools..net.cn/aideddesign/paixu_ys

更多关于PHP相关内容感兴趣的读者可查看本站专题:《php排序算法总结》、《PHP数据结构与算法教程》、《php程序设计算法总结》、《php字符串(string)用法总结》、《PHP数组(Array)操作技巧大全》、《PHP常用遍历算法与技巧总结》及《PHP数学运算技巧总结》

希望本文所述对大家PHP程序设计有所帮助。

您可能感兴趣的文章:

  • PHP排序算法之归并排序(Merging Sort)实例详解
  • PHP排序算法之快速排序(Quick Sort)及其优化算法详解
  • PHP排序算法之堆排序(Heap Sort)实例详解
  • PHP排序算法之希尔排序(Shell Sort)实例分析
  • PHP排序算法之直接插入排序(Straight Insertion Sort)实例分析
  • PHP排序算法之简单选择排序(Simple Selection Sort)实例分析
  • PHP排序算法之冒泡排序(Bubble Sort)实现方法详解
  • PHP 快速排序算法详解
  • PHP 冒泡排序算法的实现代码
  • PHP 冒泡排序 二分查找 顺序查找 二维数组排序算法函数的详解
  • PHP四种排序算法实现及效率分析【冒泡排序,插入排序,选择排序和快速排序】


  • 上一条:
    PHP排序算法之快速排序(Quick Sort)及其优化算法详解
    下一条:
    PHP排序算法之堆排序(Heap Sort)实例详解
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • Laravel从Accel获得5700万美元A轮融资(0个评论)
    • PHP 8.4 Alpha 1现已发布!(0个评论)
    • 用Time Warden监控PHP中的代码处理时间(0个评论)
    • 在PHP中使用array_pop + yield实现读取超大型目录功能示例(0个评论)
    • Property Hooks RFC在PHP 8.4中越来越接近现实(0个评论)
    • 近期文章
    • 在windows10中升级go版本至1.24后LiteIDE的Ctrl+左击无法跳转问题解决方案(0个评论)
    • 智能合约Solidity学习CryptoZombie第四课:僵尸作战系统(0个评论)
    • 智能合约Solidity学习CryptoZombie第三课:组建僵尸军队(高级Solidity理论)(0个评论)
    • 智能合约Solidity学习CryptoZombie第二课:让你的僵尸猎食(0个评论)
    • 智能合约Solidity学习CryptoZombie第一课:生成一只你的僵尸(0个评论)
    • 在go中实现一个常用的先进先出的缓存淘汰算法示例代码(0个评论)
    • 在go+gin中使用"github.com/skip2/go-qrcode"实现url转二维码功能(0个评论)
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf分页文件功能(95个评论)
    • gmail发邮件报错:534 5.7.9 Application-specific password required...解决方案(0个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2016-10
    • 2016-11
    • 2017-06
    • 2017-07
    • 2017-08
    • 2017-09
    • 2017-11
    • 2017-12
    • 2018-01
    • 2018-02
    • 2018-03
    • 2020-03
    • 2020-04
    • 2020-05
    • 2020-06
    • 2020-07
    • 2020-09
    • 2021-02
    • 2021-03
    • 2021-04
    • 2021-05
    • 2021-06
    • 2021-07
    • 2021-08
    • 2021-09
    • 2021-10
    • 2021-11
    • 2021-12
    • 2022-01
    • 2022-02
    • 2022-05
    • 2022-06
    • 2022-07
    • 2022-08
    • 2022-09
    • 2022-10
    • 2022-11
    • 2022-12
    • 2023-01
    • 2023-02
    • 2023-03
    • 2023-04
    • 2023-05
    • 2023-06
    • 2023-07
    • 2023-08
    • 2023-09
    • 2023-10
    • 2023-11
    • 2023-12
    • 2024-01
    • 2024-02
    • 2024-03
    • 2024-04
    • 2024-05
    • 2024-06
    • 2024-07
    • 2024-09
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客