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 相关文章推荐
Apache环境下PHP利用HTTP缓存协议原理解析及应用分析
Feb 16 PHP
PHP原理之异常机制深入分析
Aug 08 PHP
php的memcached客户端memcached
Jun 14 PHP
PHP调用Webservice实例代码
Jul 29 PHP
百度ping方法使用示例 自动ping百度
Jan 26 PHP
解决cPanel无法安装php5.2.17
Jun 22 PHP
php常用字符串处理函数实例分析
Nov 22 PHP
Linux系统递归生成目录中文件的md5的方法
Jun 29 PHP
php使用curl获取header检测开启GZip压缩的方法
Aug 15 PHP
PDO::errorInfo讲解
Jan 28 PHP
针对PHP开发安全问题的相关总结
Mar 22 PHP
浅谈laravel orm 中的一对多关系 hasMany
Oct 21 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版
2006/10/09 PHP
php解析json数据实例
2014/08/19 PHP
一个很简单的办法实现TD的加亮效果.
2006/06/29 Javascript
jquery 子窗口操作父窗口的代码
2009/09/21 Javascript
ExtJS Grid使用SimpleStore、多选框的方法
2009/11/20 Javascript
jquery弹出层类代码分享
2013/12/27 Javascript
JavaScript定义类的几种方式总结
2014/01/06 Javascript
node.js中的fs.lchmodSync方法使用说明
2014/12/16 Javascript
Web开发中客户端的跳转与服务器端的跳转的区别
2017/03/05 Javascript
JS实现微信里判断页面是否被分享成功的方法
2017/06/06 Javascript
Node.js 使用jade模板引擎的示例
2018/05/11 Javascript
基于Bootstrap和JQuery实现动态打开和关闭tab页的实例代码
2019/06/10 jQuery
Flutter 超实用简单菜单弹出框 PopupMenuButton功能
2019/08/06 Javascript
Python写的英文字符大小写转换代码示例
2015/03/06 Python
解决win64 Python下安装PIL出错问题(图解)
2018/09/03 Python
在windows下使用python进行串口通讯的方法
2019/07/02 Python
python3中datetime库,time库以及pandas中的时间函数区别与详解
2020/04/16 Python
Python如何优雅删除字符列表空字符及None元素
2020/06/25 Python
HTML5添加禁止缩放功能
2017/11/03 HTML / CSS
JD Sports比利时官网:英国领先的运动鞋和运动服饰零售商
2018/10/10 全球购物
俄罗斯名牌服装网上商店:UNIQUE FABRIC
2019/07/25 全球购物
某/etc/fstab文件中的某行如下: /dev/had5 /mnt/dosdata msdos defaults,usrquota 1 2 请解释其含义
2013/04/11 面试题
创业计划书六个要素
2013/12/26 职场文书
员工考核管理制度
2014/02/02 职场文书
财务出纳岗位职责
2014/02/03 职场文书
监察建议书格式
2014/05/19 职场文书
学术诚信承诺书
2014/05/26 职场文书
环境卫生标语
2014/06/09 职场文书
升国旗演讲稿
2014/09/05 职场文书
三方股份合作协议书
2014/10/13 职场文书
护士求职自荐信范文
2015/03/04 职场文书
高中生思想道德自我评价
2015/03/09 职场文书
总账会计岗位职责
2015/04/02 职场文书
2015年度物流工作总结
2015/04/30 职场文书
《追风筝的人》:人心中的成见是座大山,但请不忘初心
2019/11/15 职场文书
导游词之寿县报恩寺
2020/01/19 职场文书