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 相关文章推荐
复杂检索数据并分页显示的处理方法
Oct 09 PHP
php中的MVC模式运用技巧
May 03 PHP
PHP新手入门学习方法
May 08 PHP
PHP中让curl支持sock5的代码实例
Jan 21 PHP
smarty模板引擎从配置文件中获取数据的方法
Jan 22 PHP
php数组比较实现查找连续数的方法
Jul 29 PHP
PHP实现多维数组转字符串和多维数组转一维数组的方法
Aug 08 PHP
PHP 芝麻信用接入的注意事项
Dec 01 PHP
PHP自带方法验证邮箱、URL、IP是否合法的函数
Dec 08 PHP
PHP实现的简单组词算法示例
Apr 10 PHP
PHP APP微信提现接口代码
Sep 30 PHP
Laravel框架文件上传功能实现方法示例
Apr 16 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 操作符与控制结构
2012/03/07 PHP
apache php模块整合操作指南
2012/11/16 PHP
php实现zip压缩文件解压缩代码分享(简单易懂)
2014/05/10 PHP
IIS 7.5 asp Session超时时间设置方法
2017/04/17 PHP
Thinkphp框架+Layui实现图片/文件上传功能分析
2020/02/07 PHP
php使用Swoole实现毫秒级定时任务的方法
2020/09/04 PHP
JavaScript入门学习书籍推荐
2008/06/12 Javascript
javascript中注册和移除事件的4种方式
2013/03/20 Javascript
Knockout visible绑定使用方法
2013/11/15 Javascript
js 通用订单代码
2013/12/23 Javascript
超链接的禁用属性Disabled使用示例
2014/07/31 Javascript
js实现双击图片放大单击缩小的方法
2015/02/17 Javascript
在Javascript中处理数组之toSource()方法的使用
2015/06/09 Javascript
js实现的早期滑动门菜单效果代码
2015/08/27 Javascript
javascript实现获取浏览器版本、浏览器类型
2015/12/02 Javascript
JavaScript中的this机制
2016/01/30 Javascript
基于jQuery实现select下拉选择可输入附源码下载
2016/02/03 Javascript
JavaScript复制内容到剪贴板的两种常用方法
2018/02/27 Javascript
详解JavaScript实现动态的轮播图效果
2019/04/29 Javascript
vue动态配置模板 'component is'代码
2019/07/04 Javascript
vue中使用极验验证码的方法(附demo)
2019/12/04 Javascript
用Python的pandas框架操作Excel文件中的数据教程
2015/03/31 Python
python线程安全及多进程多线程实现方法详解
2019/09/27 Python
django实现模型字段动态choice的操作
2020/04/01 Python
Python生成并下载文件后端代码实例
2020/08/31 Python
纯CSS3实现3D旋转书本效果
2016/03/21 HTML / CSS
html5 canvas-1.canvas介绍(hello canvas)
2013/01/07 HTML / CSS
梅西酒窖:Macy’s Wine Cellar
2018/01/07 全球购物
运动会800米加油稿
2014/02/22 职场文书
晨会主持词
2014/03/17 职场文书
出生公证书样本
2014/04/04 职场文书
孝老爱亲事迹材料
2014/12/24 职场文书
2015年母亲节寄语
2015/03/23 职场文书
2015年化妆品销售工作总结
2015/05/11 职场文书
环境卫生标语
2015/08/03 职场文书