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实现验证码功能
Oct 09 PHP
php中利用post传递字符串重定向的实现代码
Apr 21 PHP
php Rename 更改文件、文件夹名称
May 24 PHP
php 读取文件头判断文件类型的实现代码
Aug 05 PHP
CodeIgniter生成网站sitemap地图的方法
Nov 13 PHP
ThinkPHP页面跳转success与error方法概述
Jun 25 PHP
php实现的九九乘法口诀表简洁版
Jul 28 PHP
PHP统计目录大小的自定义函数分享
Nov 18 PHP
php的mssql数据库连接类实例
Nov 28 PHP
WordPres对前端页面调试时的两个PHP函数使用小技巧
Dec 22 PHP
laravel 解决后端无法获取到前端Post过来的值问题
Oct 22 PHP
php ZipArchive实现多文件打包下载实例
Oct 31 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工厂模式的好处
2013/06/18 PHP
php注册审核重点解析(数据访问)
2017/05/23 PHP
PHP调用接口用post方法传送json数据的实例
2018/05/31 PHP
学习js在线html(富文本,所见即所得)编辑器
2012/12/18 Javascript
table对象中的insertRow与deleteRow使用示例
2014/01/26 Javascript
JavaScript函数的4种调用方法详解
2014/04/22 Javascript
Javascript中的方法链(Method Chaining)介绍
2015/03/15 Javascript
探讨JavaScript标签位置的存放与功能有无关系
2016/01/15 Javascript
Webpack 实现 AngularJS 的延迟加载
2016/03/02 Javascript
javascript实现鼠标点击页面 移动DIV
2016/12/02 Javascript
bootstrapValidator表单验证插件学习
2016/12/30 Javascript
js自定义Tab选项卡效果
2017/06/05 Javascript
JavaScript实现的仿新浪微博原生态输入字数即时检查功能【兼容IE6】
2017/09/26 Javascript
浅谈React + Webpack 构建打包优化
2018/01/23 Javascript
详解ES6通过WeakMap解决内存泄漏问题
2018/03/09 Javascript
浅谈Vue下使用百度地图的简易方法
2018/03/23 Javascript
浅析Vue.js 中的条件渲染指令
2018/11/19 Javascript
微信小程序实现打卡日历功能
2020/09/21 Javascript
微信小程序实现展示评分结果功能
2019/02/15 Javascript
vue-router跳转时打开新页面的两种方法
2019/07/29 Javascript
vue之debounce属性被移除及处理详解
2019/11/13 Javascript
jQuery实现简单QQ聊天框
2020/08/27 jQuery
在Python中使用poplib模块收取邮件的教程
2015/04/29 Python
Python实现批量修改文件名实例
2015/07/08 Python
Python多线程处理实例详解【单进程/多进程】
2019/01/30 Python
Pytorch实现基于CharRNN的文本分类与生成示例
2020/01/08 Python
python 数据分析实现长宽格式的转换
2020/05/18 Python
python statsmodel的使用
2020/12/21 Python
python基于opencv 实现图像时钟
2021/01/04 Python
Html5实现用户注册自动校验功能实例代码
2016/05/24 HTML / CSS
Orvis官网:自1856年以来,优质服装、飞钓装备等
2018/12/17 全球购物
外贸业务员求职自荐信分享
2013/09/21 职场文书
学生档案自我鉴定
2013/10/07 职场文书
城市规划毕业生求职信
2013/10/10 职场文书
普希金的诗歌赏析(3首)
2019/08/20 职场文书
MySQL sql_mode修改不生效的原因及解决
2021/05/07 MySQL