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开发工具之vs2005图解
Jan 12 PHP
php jquery 实现新闻标签分类与无刷新分页
Dec 18 PHP
PHP得到某段时间区间的时间戳 php定时任务
Apr 12 PHP
XAMPP安装与使用方法详细解析
Nov 27 PHP
php实现查看邮件是否已被阅读的方法
Dec 03 PHP
php比较两个绝对时间的大小
Jan 31 PHP
jQuery中的RadioButton,input,CheckBox取值赋值实现代码
Feb 18 PHP
php实现的简单美国商品税计算函数
Jul 13 PHP
php array_pop 删除数组最后一个元素实例
Nov 02 PHP
php微信公众号js-sdk开发应用
Nov 28 PHP
PHP调用API接口实现天气查询功能的示例
Sep 21 PHP
php中对象引用和复制实例分析
Aug 14 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
Laravel5中contracts详解
2015/03/02 PHP
DOM Scripting中的图片切换[兼容Firefox]
2010/06/12 Javascript
jQuery页面加载初始化常用的三种方法
2014/06/04 Javascript
JavaScript中的Web worker多线程API研究
2014/12/06 Javascript
js的toLowerCase方法用法实例
2015/01/27 Javascript
运行Node.js的IIS扩展iisnode安装配置笔记
2015/03/02 Javascript
jQuery+HTML5+CSS3制作支持响应式布局时间轴插件
2016/08/10 Javascript
清除输入框内的空格
2016/12/21 Javascript
深入理解Angularjs向指令传递数据双向绑定机制
2016/12/31 Javascript
jquery实现左右滑动式轮播图
2017/03/02 Javascript
javaScript日期工具类DateUtils详解
2017/12/08 Javascript
vuejs实现折叠面板展开收缩动画效果
2018/09/06 Javascript
Vue递归实现树形菜单方法实例
2018/11/06 Javascript
JS监听事件的叠加和移除功能
2018/11/19 Javascript
element-ui组件中input等的change事件中传递自定义参数
2019/05/22 Javascript
koa2+vue实现登陆及登录状态判断
2019/08/15 Javascript
layer页面跳转,获取html子节点元素的值方法
2019/09/27 Javascript
基于vue和websocket的多人在线聊天室
2020/02/01 Javascript
原生JavaScript实现随机点名表
2021/01/14 Javascript
Python多线程编程(二):启动线程的两种方法
2015/04/05 Python
Python使用CMD模块更优雅的运行脚本
2015/05/11 Python
python中requests和https使用简单示例
2018/01/18 Python
python numpy矩阵信息说明,shape,size,dtype
2020/05/22 Python
CSS实现的一闪而过的图片闪光效果
2014/04/23 HTML / CSS
Finishline官网:美国一家领先的运动品牌鞋类、服装零售商
2016/07/20 全球购物
阿里健康大药房:阿里自营网上药店
2017/08/01 全球购物
学校司机岗位职责
2013/11/14 职场文书
十月份红领巾广播稿
2014/01/22 职场文书
师范生求职信
2014/06/14 职场文书
火箭队口号
2014/06/18 职场文书
刘公岛导游词
2015/02/05 职场文书
综合测评自我评价
2015/03/06 职场文书
培根随笔读书笔记
2015/07/01 职场文书
2016国庆节67周年寄语
2015/12/07 职场文书
党风廉政教育心得体会2016
2016/01/22 职场文书
《吸血鬼:避世 血猎》官宣4.27发售 系列首款大逃杀
2022/04/03 其他游戏