php计数排序算法的实现代码(附四个实例代码)


Posted in PHP onMarch 31, 2020

计数排序只适合使用在键的变化不大于元素总数的情况下。它通常用作另一种排序算法(基数排序)的子程序,这样可以有效地处理更大的键。

总之,计数排序是一种稳定的线性时间排序算法。计数排序使用一个额外的数组C ,其中第i个元素是待排序数组 A中值等于 i的元素的个数。然后根据数组C 来将A中的元素排到正确的位置。

通常计数排序算法的实现步骤思路是:

1.找出待排序的数组中最大和最小的元素;

2.统计数组中每个值为i的元素出现的次数,存入数组C的第i项;

3.对所有的计数累加(从C中的第一个元素开始,每一项和前一项相加);

4.反向填充目标数组:将每个元素i放在新数组的第C[i]项,每放一个元素就将C[i]减去1。

PHP计数排序算法的实现代码示例如下:

<?php
function counting_sort($my_array, $min, $max)
{
  $count = array();
  for($i = $min; $i <= $max; $i++)
  {
    $count[$i] = 0;
  }
 
  foreach($my_array as $number)
  {
    $count[$number]++;
  }
  $z = 0;
  for($i = $min; $i <= $max; $i++) {
    while( $count[$i]-- > 0 ) {
      $my_array[$z++] = $i;
    }
  }
  return $my_array;
}
$test_array = array(3, 0, 2, 5, -1, 4, 1);
echo "原始数组 :\n";
echo implode(', ',$test_array );
echo "\n排序后数组\n:";
echo implode(', ',counting_sort($test_array, -1, 5)). PHP_EOL;

输出:

原始数组 : 3, 0, 2, 5, -1, 4, 1

排序后数组 :-1, 0, 1, 2, 3, 4, 5

下面补充一个例子

1、计数排序只适用于整数在小范围内排序

<?php
$arr = [95,94,91,98,99,90,99,93,91,92];
function countSort($arr){
$max = $arr[0];
$min = $arr[0];
for($i=0;$i<count($arr);$i++){
if($arr[$i]>$max){
$max = $arr[$i];
}
if($arr[$i] < $min){
$min = $arr[$i];
}
}
try{
$frequency = new SplFixedArray($max-$min+1);
for($i=0;$i<count($arr);$i++){
if(empty($frequency[$arr[$i]-$min]))
$frequency[$arr[$i]-$min] = 0;
$frequency[$arr[$i]-$min] += 1;
}

$sum = 0;
for ($i=0; $i < count($frequency); $i++) {
$sum += $frequency[$i];
$frequency[$i] = $sum;
}

$splfixed = new SplFixedArray(count($arr));

for($i=(count($arr)-1);$i>=0;$i--){
$splfixed[$frequency[$arr[$i]-$min]-1] = $arr[$i];
$frequency[$arr[$i]-$min] -= 1;
}
}catch(RuntimeException $re){
echo "RuntimeException: ".$re->getMessage()."\n";
}
print_r($splfixed->toArray());
}
countSort($arr);
?>

输出

Array
(
    [0] => 90
    [1] => 91
    [2] => 91
    [3] => 92
    [4] => 93
    [5] => 94
    [6] => 95
    [7] => 98
    [8] => 99
    [9] => 99
)

2、php计数排序

获取序列中的最小值min和最大值max O(n)
统计min - max之间所有值在序列中的出现次数 O(n)
顺序输出min - max的所有值,次数为0不输出,其余次数为多少就输出多少 O(k) k为数据范围

例如序列为: 2, 4, 6, 9, 4, 8

min = 2, max = 9, n为6,k为8

统计出现次数为

[2 => 1, 3 => 0, 4 => 2, 5 => 0, 6 => 1, 7 => 0, 8 => 1, 9 => 1]

输出结果为

2, 4, 4, 6, 8, 9

很明显,计数排序的复杂度为O(n) + O(k),也就是和数据量和数据范围有关.
若n和k相近,则可认为是O(n)
同时,因为要统计出现次数,如果数据范围过大而数据又很稀疏,造成的空间浪费比较大

class CountSort
{
  private $originalData = [];
  private $rangeMap = [];
  private $resultData = [];

  public function __construct($original = [])
  {
    $this->originalData = $original;
  }

  public function sort()
  {
    list($min, $max) = $this->calculateDataRange();
    $this->statisticNumberOfOccurrence($min, $max);
    $this->resultData = $this->generateResult();
    return $this->resultData;
  }

  protected function calculateDataRange()
  {
    $max = null;
    $min = null;

    foreach ($this->originalData as $value) {
      if (!is_null($max)) {
        if ($value > $max) {
          $max = $value;
        }
      } else {
        $max = $value;
      }

      if (!is_null($min)) {
        if ($value < $min) {
          $min = $value;
        }
      } else {
        $min = $value;
      }
    }

    return [$min, $max];
  }

  protected function statisticNumberOfOccurrence($min, $max)
  {
    for ($i = $min; $i <= $max; $i++) {
      $this->rangeMap[$i] = 0;
    }

    foreach ($this->originalData as $value) {
      $this->rangeMap[$value]++;
    }
  }

  protected function generateResult()
  {
    $result = [];

    foreach ($this->rangeMap as $key => $value) {
      if ($value != 0) {
        for ($i = 0; $i < $value; $i++) {
          array_push($result, $key);
        }
      }
    }
    return $result;
  }
}

$testData = [2, 3, 4, 3, 10, 30, 20, 15, 10, 12, 33];

$countSort = new CountSort($testData);
echo '<pre>';
var_dump($countSort->sort());

输出

<pre>array(11) {
  [0]=>
  int(2)
  [1]=>
  int(3)
  [2]=>
  int(3)
  [3]=>
  int(4)
  [4]=>
  int(10)
  [5]=>
  int(10)
  [6]=>
  int(12)
  [7]=>
  int(15)
  [8]=>
  int(20)
  [9]=>
  int(30)
  [10]=>
  int(33)
}

到此这篇关于php计数排序算法的实现代码的文章就介绍到这了,更多相关php计数排序内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

PHP 相关文章推荐
php关于array_multisort多维数组排序的使用说明
Jan 04 PHP
php数组函数序列之next() - 移动数组内部指针到下一个元素的位置,并返回该元素值
Oct 31 PHP
CodeIgniter图像处理类的深入解析
Jun 17 PHP
国外十大最流行的PHP框架排名
Jul 04 PHP
php实现水仙花数示例分享
Apr 03 PHP
php与flash as3 socket通信传送文件实现代码
Aug 16 PHP
CodeIgniter删除和设置Cookie的方法
Apr 07 PHP
微信公众号开发客服接口实例代码
Oct 21 PHP
PHP中检索字符串的方法分析【strstr与substr_count方法】
Feb 17 PHP
PHP培训要多少钱
Jun 06 PHP
php安装扩展mysqli的实现步骤及报错解决办法
Sep 23 PHP
php的扩展写法总结
May 14 PHP
php设计模式之观察者模式实例详解【星际争霸游戏案例】
Mar 30 #PHP
TP5框架实现上传多张图片的方法分析
Mar 29 #PHP
thinkphp框架无限级栏目的排序功能实现方法示例
Mar 29 #PHP
php查看一个变量的占用内存的实例代码
Mar 29 #PHP
tp5框架前台无限极导航菜单类实现方法分析
Mar 29 #PHP
PHP中类与对象功能、用法实例解读
Mar 27 #PHP
php设计模式之职责链模式实例分析【星际争霸游戏案例】
Mar 27 #PHP
You might like
给初学PHP的5个入手程序
2006/11/23 PHP
使用PHP数组实现无限分类,不使用数据库,不使用递归.
2006/12/09 PHP
用PHP代替JS玩转DOM的思路及示例代码
2014/06/15 PHP
smarty自定义函数htmlcheckboxes用法实例
2015/01/22 PHP
PHP字典树(Trie树)定义与实现方法示例
2017/10/09 PHP
TP5(thinkPHP5)框架使用ajax实现与后台数据交互的方法小结
2020/02/10 PHP
JavaScript Array扩展实现代码
2009/10/14 Javascript
jQuery+JSON+jPlayer实现QQ空间音乐查询功能示例
2013/06/17 Javascript
JS实现Fisheye效果动感放大菜单代码
2015/10/21 Javascript
js代码实现点击按钮出现60秒倒计时
2021/01/28 Javascript
JS 获取HTML标签内的子节点的方法
2016/09/21 Javascript
jquery获取easyui日期控件的值实现方法
2016/11/09 Javascript
vue.js动态数据绑定学习笔记
2017/05/19 Javascript
vue 动态修改a标签的样式的方法
2018/01/18 Javascript
vue的常用组件操作方法应用分析
2018/04/13 Javascript
Vue Router去掉url中默认的锚点#
2018/08/01 Javascript
react 兄弟组件如何调用对方的方法示例
2018/10/23 Javascript
关于微信公众号开发无法支付的问题解决
2018/12/28 Javascript
微信小程序MUI侧滑导航菜单示例(Popup弹出式,左侧不动,右侧滑动)
2019/01/23 Javascript
详解微信小程序回到顶部的两种方式
2019/05/09 Javascript
Vue商品控件与购物车联动效果的实例代码
2019/07/21 Javascript
[06:45]DOTA2卡尔工作室 英雄介绍幻影长矛手篇
2013/07/12 DOTA
[02:38]2018DOTA2亚洲邀请赛赛前采访-VGJ.T
2018/04/03 DOTA
解决python web项目意外关闭,但占用端口的问题
2019/12/17 Python
Tensorflow实现部分参数梯度更新操作
2020/01/23 Python
Python实现计算图像RGB均值方式
2020/06/04 Python
Django nginx配置实现过程详解
2020/09/10 Python
协程Python 中实现多任务耗资源最小的方式
2020/10/19 Python
施华洛世奇美国官网:SWAROVSKI美国
2018/02/08 全球购物
澳大利亚优质的家居用品和生活方式公司:Bed Bath N’ Table
2019/04/16 全球购物
应届生妇产科护士求职信
2013/10/27 职场文书
事业单位分类改革实施方案
2014/03/21 职场文书
社团活动总结报告
2014/06/27 职场文书
改革共识倡议书
2014/08/29 职场文书
社区母亲节活动总结
2015/02/10 职场文书
Redis Lua脚本实现ip限流示例
2022/07/15 Redis