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 相关文章推荐
PHP4与PHP5的时间格式问题
Feb 17 PHP
php中var_export与var_dump的区别分析
Aug 21 PHP
开启CURL扩展,让服务器支持PHP curl函数(远程采集)
Mar 19 PHP
PHP应用JSON技巧讲解
Feb 03 PHP
如何阻止网站被恶意反向代理访问(防网站镜像)
Mar 18 PHP
php实现根据url自动生成缩略图的方法
Sep 23 PHP
ThinkPHP模型详解
Jul 27 PHP
PHP实现仿百度文库,豆丁在线文档效果(word,excel,ppt转flash)
Mar 10 PHP
Zend Framework教程之Zend_Config_Ini用法分析
Mar 23 PHP
php实现的二叉树遍历算法示例
Jun 15 PHP
PHP中引用类型和值类型功能与用法示例
Feb 26 PHP
thinkPHP和onethink微信支付插件分享
Aug 11 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 获得汉字拼音首字母的函数
2009/08/01 PHP
php数据结构之顺序链表与链式线性表示例
2018/01/22 PHP
jquery提升性能最佳实践小结
2010/12/06 Javascript
javascript数组去掉重复
2011/05/12 Javascript
jquery表单验证使用插件formValidator
2012/11/10 Javascript
nodejs开发环境配置与使用
2014/11/17 NodeJs
jQuery中scrollLeft()方法用法实例
2015/01/16 Javascript
js实现适合新闻类图片的轮播效果
2017/02/05 Javascript
Ionic2开发环境搭建教程
2020/08/20 Javascript
AngularJS中ng-class用法实例分析
2017/07/06 Javascript
HTML5开发Kinect体感游戏的实例应用
2017/09/18 Javascript
利用HBuilder打包前端开发webapp为apk的方法
2017/11/13 Javascript
使用Bootstrap4 + Vue2实现分页查询的示例代码
2017/12/21 Javascript
JavaScript函数apply()和call()用法与异同分析
2018/08/10 Javascript
layui自定义ajax左侧三级菜单
2019/07/26 Javascript
微信小程序模板消息限制实现无限制主动推送的示例代码
2019/08/27 Javascript
javascript设计模式 ? 单例模式原理与应用实例分析
2020/04/09 Javascript
微信小程序自定义顶部组件customHeader的示例代码
2020/06/03 Javascript
vue 函数调用加括号与不加括号的区别
2020/10/29 Javascript
[03:56]还原FTP电影首映式 DOTA2群星拼出遗迹世界
2014/03/26 DOTA
Python中用Descriptor实现类级属性(Property)详解
2014/09/18 Python
使用Python制作获取网站目录的图形化程序
2015/05/04 Python
python查找指定具有相同内容文件的方法
2015/06/28 Python
Python3连接MySQL(pymysql)模拟转账实现代码
2016/05/24 Python
在python中实现对list求和及求积
2018/11/14 Python
Python 3.x基于Xml数据的Http请求方法
2018/12/28 Python
python中使用paramiko模块并实现远程连接服务器执行上传下载功能
2020/02/29 Python
python绘制汉诺塔
2021/03/01 Python
英国网上自行车商店:Tredz Bikes
2019/10/29 全球购物
北京RT科技有限公司.net工程师面试题
2013/02/15 面试题
团队队名口号大全
2014/06/06 职场文书
纪念九一八事变演讲稿:青少年应树立远大理想
2014/09/14 职场文书
党员对照检查材料
2014/09/22 职场文书
《坐井观天》教学反思
2016/02/18 职场文书
spring cloud gateway中如何读取请求参数
2021/07/15 Java/Android