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 相关文章推荐
第八节 访问方式 [8]
Oct 09 PHP
PHP中的函数嵌套层数限制分析
Jun 13 PHP
PHP自定义大小验证码的方法详解
Jun 07 PHP
深入php处理整数函数的详解
Jun 09 PHP
PHP中的Streams详细介绍
Nov 12 PHP
php创建session的方法实例详解
Jan 27 PHP
给PHP开发者的编程指南 第一部分降低复杂程度
Jan 18 PHP
php实现简单爬虫的开发
Mar 28 PHP
PHP中set_include_path()函数相关用法分析
Jul 18 PHP
PHP简单实现记录网站访问量功能示例
Jun 06 PHP
PHP+Oracle本地开发环境搭建方法详解
Apr 01 PHP
Laravel5.5+ 使用API Resources快速输出自定义JSON方法详解
Apr 06 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/06/21 PHP
php微信开发之关键词回复功能
2018/06/13 PHP
实例:尽可能写友好的Javascript代码
2006/10/09 Javascript
用javascript getComputedStyle获取和设置style的原理
2008/10/10 Javascript
JavaScript写的一个自定义弹出式对话框代码
2010/01/17 Javascript
jQuery代码优化 事件委托篇
2011/11/01 Javascript
JavaScript转换农历类实现及调用方法
2013/01/27 Javascript
js弹出模式对话框,并接收回传值的方法
2013/03/12 Javascript
js Select下拉列表框进行多选、移除、交换内容的具体实现方法
2013/08/13 Javascript
JavaScript 变量、作用域及内存
2015/04/08 Javascript
javascript实现倒计时并弹窗提示特效
2015/06/05 Javascript
JS组件Form表单验证神器BootstrapValidator
2016/01/26 Javascript
connection reset by peer问题总结及解决方案
2016/10/21 Javascript
微信开发 JS-SDK 6.0.2 经常遇到问题总结
2016/12/08 Javascript
jQuery Ajax实现跨域请求
2017/01/21 Javascript
详解Node.js开发中的express-session
2017/05/19 Javascript
Webpack 服务器端代码打包的示例代码
2017/09/19 Javascript
使用webpack-dev-server处理跨域请求的方法
2018/04/18 Javascript
JS实现简单的抽奖转盘效果示例
2019/02/16 Javascript
vue递归组件实战之简单树形控件实例代码
2019/08/27 Javascript
基于Angular 8和Bootstrap 4实现动态主题切换的示例代码
2020/02/11 Javascript
OpenLayers3实现地图鹰眼以及地图比例尺的添加
2020/09/25 Javascript
element el-table表格的二次封装实现(附表格高度自适应)
2021/01/19 Javascript
Python机器学习之K-Means聚类实现详解
2018/02/22 Python
Transpose 数组行列转置的限制方式
2020/02/11 Python
详解CSS3的图层阴影和文字阴影效果使用
2016/06/09 HTML / CSS
HTML5 Canvas入门学习教程
2016/03/17 HTML / CSS
法国和欧洲海边和滑雪度假:Pierre & Vacances
2017/01/04 全球购物
香港草莓网:Strawberrynet香港
2019/05/10 全球购物
如何将无状态会话Bean发布为WEB服务,只有无状态会话Bean可以发布为WEB服务?
2015/12/03 面试题
文化建设工作方案
2014/05/12 职场文书
2014法制宣传日活动总结
2014/07/09 职场文书
龙门石窟导游词
2015/02/02 职场文书
世界卫生日宣传活动总结
2015/02/09 职场文书
机修车间主任岗位职责
2015/04/08 职场文书
Pytorch 如何实现常用正则化
2021/05/27 Python