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录入页面中动态从数据库中提取数据的实现
Oct 09 PHP
解决dede生成静态页和动态页转换的一些问题,及火车采集入库生成动态的办法
Mar 29 PHP
如何使用FireFox插件FirePHP调试PHP
Jul 23 PHP
PHP CURL CURLOPT参数说明(curl_setopt)
Sep 30 PHP
php用正则表达式匹配URL的简单方法
Nov 12 PHP
MyEclipse常用配置图文教程
Sep 11 PHP
ThinkPHP基于PHPExcel导入Excel文件的方法
Oct 15 PHP
php+mysqli实现将数据库中一张表信息打印到表格里的方法
Jan 28 PHP
分享微信扫码支付开发遇到问题及解决方案-附Ecshop微信支付插件
Aug 23 PHP
CI映射(加载)数据到view层的方法
Mar 28 PHP
PHP框架laravel的.env文件配置教程
Jun 07 PHP
Yii框架小部件(Widgets)用法实例详解
May 15 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
vBulletin HACK----关于排版的两个HACK
2006/10/09 PHP
Could not load type System.ServiceModel.Activation.HttpModule解决办法
2012/12/29 PHP
简单解析PHP程序的运行流程
2016/06/23 PHP
PHP sleep()函数, usleep()函数
2016/08/25 PHP
PHP实现的操作数组类库定义与用法示例
2019/05/24 PHP
Laravel 自动转换长整型雪花 ID 为字符串的实现
2020/10/27 PHP
说说掌握JavaScript语言的思想前提想学习js的朋友可以看看
2009/04/01 Javascript
浅谈Javascript事件处理程序的几种方式
2012/06/27 Javascript
JavaScript中的style.display属性操作
2013/03/27 Javascript
jQuery实现用户注册的表单验证示例
2013/08/28 Javascript
jQuery如何获取同一个类标签的所有值(默认无法获取)
2014/09/25 Javascript
jQuery $.each遍历对象、数组用法实例
2015/04/16 Javascript
深入理解JavaScript中的for循环
2017/02/07 Javascript
jQuery实现的动态文字变化输出效果示例【附演示与demo源码下载】
2017/03/24 jQuery
浅谈vue项目重构技术要点和总结
2018/01/23 Javascript
node实现登录图片验证码的示例代码
2018/04/20 Javascript
javascript删除数组元素的七个方法示例
2019/09/09 Javascript
微信小程序 下拉刷新及上拉加载原理解析
2019/11/06 Javascript
[54:02]2018DOTA2亚洲邀请赛 4.1 小组赛 B组 IG vs VGJ.T
2018/04/03 DOTA
python 读取文件并把矩阵转成numpy的两种方法
2019/02/12 Python
我就是这样学习Python中的列表
2019/06/02 Python
Pytorch释放显存占用方式
2020/01/13 Python
python实现字符串和数字拼接
2020/03/02 Python
python如何进入交互模式
2020/07/06 Python
基于 Python 实践感知器分类算法
2021/01/07 Python
通过Canvas及File API缩放并上传图片完整示例
2013/08/08 HTML / CSS
俄罗斯香水和化妆品购物网站:Л’Этуаль
2018/05/10 全球购物
最便宜促销价格订机票:Airpaz(总部设在印尼,支持中文)
2018/11/13 全球购物
什么时候用assert
2015/05/08 面试题
后勤人员自我评价怎么写
2013/09/19 职场文书
采购部部门职责
2013/12/15 职场文书
劳动争议和解协议书范本
2014/11/20 职场文书
2014年移动公司工作总结
2014/12/08 职场文书
解决Jupyter-notebook不弹出默认浏览器的问题
2021/03/30 Python
老生常谈 使用 CSS 实现三角形的技巧(多种方法)
2021/04/13 HTML / CSS
JavaScript中时间格式化新思路toLocaleString()
2021/11/07 Javascript