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中$this-&amp;gt;含义分析
Nov 29 PHP
遍历指定目录下的所有目录和文件的php代码
Nov 27 PHP
支持中文字母数字、自定义字体php验证码代码
Feb 27 PHP
php全局变量和类配合使用深刻理解
Jun 05 PHP
ci检测是ajax还是页面post提交数据的方法
Nov 10 PHP
在Windows XP下安装Apache+MySQL+PHP环境
Feb 22 PHP
微信公众号模板消息群发php代码示例
Dec 29 PHP
自制PHP框架之模型与数据库
May 07 PHP
PHP基于自定义函数实现的汉字转拼音功能实例
Sep 30 PHP
Thinkphp5框架ajax接口实现方法分析
Aug 28 PHP
Laravel框架之解决前端显示图片问题
Oct 24 PHP
PHP内存溢出优化代码详解
Feb 26 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 增加了对 .ZIP 文件的读取功能
2006/10/09 PHP
php curl抓取网页的介绍和推广及使用CURL抓取淘宝页面集成方法
2015/11/30 PHP
PHP+AJAX 投票器功能
2017/11/11 PHP
PHP abstract 抽象类定义与用法示例
2018/05/29 PHP
基于Asp.net与Javascript控制的日期控件
2010/05/22 Javascript
window.addEventListener来解决让一个js事件执行多个函数
2012/12/26 Javascript
jQuery aminate方法定位到页面具体位置
2013/12/26 Javascript
jQuery实现图片轮播特效代码分享
2015/09/15 Javascript
详解JavaScript表单验证(E-mail 验证)
2016/03/31 Javascript
使用jQuery UI库开发Web界面的简单入门指引
2016/04/22 Javascript
JavaScript中的跨浏览器事件操作的基本方法整理
2016/05/20 Javascript
javascript闭包概念简单解析(推荐)
2016/06/03 Javascript
功能强大的Bootstrap使用手册(一)
2016/08/02 Javascript
BootStrap table删除指定行的注意事项(笔记整理)
2017/02/05 Javascript
本地搭建微信小程序服务器的实现方法
2017/10/27 Javascript
p5.js入门教程之键盘交互
2018/03/19 Javascript
Vue根据条件添加click事件的方式
2019/11/09 Javascript
JavaScript实现指定数量的并发限制的示例代码
2020/03/10 Javascript
vue a标签点击实现赋值方式
2020/09/07 Javascript
python打开网页和暂停实例
2014/09/30 Python
Python中的推导式使用详解
2015/06/03 Python
在Django框架中编写Contact表单的教程
2015/07/17 Python
基于python爬虫数据处理(详解)
2017/06/10 Python
Python Pillow Image Invert
2019/01/22 Python
Python搭建Keras CNN模型破解网站验证码的实现
2020/04/07 Python
Python自定义聚合函数merge与transform区别详解
2020/05/26 Python
浅谈tensorflow 中的图片读取和裁剪方式
2020/06/30 Python
Tom Dixon官网:英国照明及家具设计和制造公司
2019/03/01 全球购物
如何写一份好的自荐信
2014/01/02 职场文书
新闻专业毕业生英文求职信
2014/03/19 职场文书
活动总结怎么写啊
2014/05/07 职场文书
党的群众路线教育实践活动宣传标语口号
2014/06/06 职场文书
运动员口号
2014/06/09 职场文书
新娘父亲婚礼致辞
2015/07/27 职场文书
MySQL创建管理RANGE分区
2022/04/13 MySQL
python内置模块之上下文管理contextlib
2022/06/14 Python