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 相关文章推荐
mysql5详细安装教程
Jan 15 PHP
实用函数9
Nov 08 PHP
php 保留字列表
Oct 04 PHP
PHP获取POST数据的几种方法汇总
Mar 03 PHP
摘自织梦CMS中的图片处理类
Aug 08 PHP
php中使用GD库做验证码
Mar 31 PHP
PHP使用反射机制实现查找类和方法的所在位置
Apr 22 PHP
PHP面试常用算法(推荐)
Jul 22 PHP
php rsa 加密,解密,签名,验签详解
Dec 06 PHP
Laravel5.5新特性之友好报错以及展示详解
Aug 13 PHP
Yii2框架实现利用mpdf创建pdf文件功能示例
Feb 08 PHP
PHP标准库 (SPL)――Countable用法示例
Jun 05 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
destoon实现不同会员组公司名称显示不同的颜色的方法
2014/08/22 PHP
yii2.0之GridView自定义按钮和链接用法
2014/12/15 PHP
php判断str字符串是否是xml格式数据的方法示例
2017/07/26 PHP
php判断目录存在的简单方法
2019/09/26 PHP
javascript 延迟加载技术(lazyload)简单实现
2011/01/17 Javascript
jquery插件珍藏(图片局部放大/信息提示框)
2013/01/08 Javascript
Javascript判断对象是否相等实现代码
2013/03/18 Javascript
js+html5实现canvas绘制简单矩形的方法
2015/06/05 Javascript
JQuery标签页效果的两个实例讲解(4)
2015/09/17 Javascript
jQuery学习笔记之Ajax用法实例详解
2015/12/01 Javascript
jQuery 实现评论等级好评差评特效
2016/05/06 Javascript
JQuery异步加载PartialView的方法
2016/06/07 Javascript
Javascript 实现全屏滚动实例代码
2016/12/31 Javascript
JavaScript的for循环中嵌套一个点击事件的问题解决
2017/03/03 Javascript
jQuery复合事件用法示例
2017/06/10 jQuery
nodejs操作mongodb的填删改查模块的制作及引入实例
2018/01/02 NodeJs
解决layui前端框架 form表单,table表等内置控件不显示的问题
2018/08/19 Javascript
Vue组件通信的几种实现方法
2019/04/25 Javascript
elementUi vue el-radio 监听选中变化的实例代码
2019/06/28 Javascript
nodejs和react实现即时通讯简易聊天室功能
2019/08/21 NodeJs
layui表格分页 记录勾选的实例
2019/09/02 Javascript
js防抖函数和节流函数使用场景和实现区别示例分析
2020/04/11 Javascript
JS array数组检测方式解析
2020/05/19 Javascript
用Python制作检测Linux运行信息的工具的教程
2015/04/01 Python
用Python编写一个简单的Lisp解释器的教程
2015/04/03 Python
在arcgis使用python脚本进行字段计算时是如何解决中文问题的
2015/10/18 Python
Python 修改列表中的元素方法
2018/06/26 Python
详解Django项目中模板标签及模板的继承与引用(网站中快速布置广告)
2019/03/27 Python
Python OpenCV利用笔记本摄像头实现人脸检测
2020/08/20 Python
python如何实现不可变字典inmutabledict
2020/01/08 Python
使用Python webdriver图书馆抢座自动预约的正确方法
2021/03/04 Python
Canvas 帧动画吃苹果小游戏
2020/08/05 HTML / CSS
上海微创软件面试题
2012/06/14 面试题
中学教师岗位职责
2013/11/26 职场文书
天鹅的故事教学反思
2014/02/04 职场文书
纯 CSS 自定义多行省略的问题(从原理到实现)
2021/11/11 HTML / CSS