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调用Oracle存储过程
Oct 09 PHP
多php服务器实现多session并发运行
Oct 09 PHP
完美解决dedecms中的[html][/html]和[code][/code]问题
Mar 20 PHP
php设置编码格式的方法
Mar 05 PHP
测试php连接mysql是否成功的代码分享
Jan 24 PHP
PHP生成树的方法
Jul 28 PHP
WordPress中对访客评论功能的一些优化方法
Nov 24 PHP
thinkphp跨库操作的简单代码实例
Sep 22 PHP
Laravel框架实现简单的学生信息管理平台案例
May 07 PHP
php中的钩子理解及应用实例分析
Aug 30 PHP
在laravel中实现ORM模型使用第二个数据库设置
Oct 24 PHP
PHP RabbitMQ消息列队
May 11 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
php5.5新数组函数array_column使用
2013/07/08 PHP
浅析虚拟主机服务器php fsockopen函数被禁用的解决办法
2013/08/07 PHP
php生成excel列名超过26列大于Z时的解决方法
2014/12/29 PHP
PHP Beanstalkd消息队列的安装与使用方法实例详解
2020/02/21 PHP
PHP大文件及断点续传下载实现代码
2020/08/18 PHP
新浪刚打开页面出来的全屏广告代码
2007/04/02 Javascript
JavaScript Cookie的读取和写入函数
2009/12/08 Javascript
JQery 渐变图片导航效果代码 漂亮
2010/01/01 Javascript
自己做的模拟模态对话框实现代码
2012/05/23 Javascript
使用POST方式弹出窗口的两种方法示例介绍
2014/01/29 Javascript
jquery动态加载js/css文件方法(自写小函数)
2014/10/11 Javascript
用NODE.JS中的流编写工具是要注意的事项
2016/03/01 Javascript
angularjs 源码解析之injector
2016/08/22 Javascript
详解js数组的完全随机排列算法
2016/12/16 Javascript
JavaScript脚本语言是什么_动力节点Java学院整理
2017/06/26 Javascript
浅谈webpack SplitChunksPlugin实用指南
2018/09/17 Javascript
Vue基于vuex、axios拦截器实现loading效果及axios的安装配置
2019/04/26 Javascript
[52:27]2018DOTA2亚洲邀请赛 3.31 小组赛B组 paiN vs Secret
2018/04/01 DOTA
详谈Python中列表list,元祖tuple和numpy中的array区别
2018/04/18 Python
python爬虫自动创建文件夹的功能
2018/08/01 Python
解决pycharm启动后总是不停的updating indices...indexing的问题
2019/11/27 Python
Ubuntu权限不足无法创建文件夹解决方案
2020/11/14 Python
关于前端上传文件全面基础扫盲贴(入门)
2019/08/01 HTML / CSS
全球性的在线时尚男装零售商:boohooMAN
2016/12/17 全球购物
菲律宾旅游网站:Expedia菲律宾
2017/10/11 全球购物
计算机专业毕业生推荐信
2013/11/25 职场文书
汽车维修专业毕业生的求职信分享
2013/12/04 职场文书
化学教师自荐信范文
2013/12/28 职场文书
小学数学教学反思
2014/02/02 职场文书
会计学自荐信
2014/06/03 职场文书
环境科学专业教师求职信
2014/07/12 职场文书
2014国庆节主题活动方案:快乐的国庆节
2014/09/16 职场文书
三年级学生评语大全
2014/12/26 职场文书
反腐倡廉观后感
2015/06/08 职场文书
导游词之广东佛山(南风古灶)
2019/09/24 职场文书
Python入门之基础语法详解
2021/05/11 Python