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 相关文章推荐
模拟OICQ的实现思路和核心程序(二)
Oct 09 PHP
PHP脚本数据库功能详解(中)
Oct 09 PHP
php expects parameter 1 to be resource, array given 错误
Mar 23 PHP
基于PHP对XML的操作详解
Jun 07 PHP
PHP echo,print,printf,sprintf函数之间的区别与用法详解
Nov 27 PHP
smarty模板中使用get、post、request、cookies、session变量的方法
Apr 24 PHP
yii实现创建验证码实例解析
Jul 31 PHP
ThinkPHP结合AjaxFileUploader实现无刷新文件上传的方法
Oct 29 PHP
php实现Session存储到Redis
Nov 11 PHP
php数据库的增删改查 php与javascript之间的交互
Aug 31 PHP
php测试kafka项目示例
Feb 06 PHP
PHP7 标准库修改
Mar 09 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
thinkphp框架下404页面设置 仅三步
2016/05/14 PHP
三个思路解决laravel上传文件报错:413 Request Entity Too Large问题
2017/11/13 PHP
tp5.1 框架路由操作-URL生成实例分析
2020/05/26 PHP
jQuery Ajax文件上传(php)
2009/06/16 Javascript
jQuery一步一步实现跨浏览器的可编辑表格,支持IE、Firefox、Safari、Chrome、Opera
2009/08/28 Javascript
javascript三种代码注释方法
2016/06/02 Javascript
三种方式实现瀑布流布局
2017/02/10 Javascript
JS正则表达式验证账号、手机号、电话和邮箱是否合法
2017/03/08 Javascript
详解webpack 配合babel 将es6转成es5 超简单实例
2017/05/02 Javascript
详解node中创建服务进程
2017/05/09 Javascript
详解webpack的配置文件entry与output
2017/08/21 Javascript
layer 刷新某个页面的实现方法
2019/09/05 Javascript
Vue toFixed保留两位小数的3种方式
2020/10/23 Javascript
原生JS实现pc端轮播图效果
2020/12/21 Javascript
详解Vue.js 可拖放文本框组件的使用
2021/03/03 Vue.js
状态机的概念和在Python下使用状态机的教程
2015/04/11 Python
Python数据分析之真实IP请求Pandas详解
2016/11/18 Python
Python实现字典的遍历与排序功能示例
2017/12/23 Python
浅谈python可视化包Bokeh
2018/02/07 Python
Python django框架输入汉字,数字,字符生成二维码实现详解
2019/09/24 Python
python使用turtle库绘制奥运五环
2020/02/24 Python
Python打包工具PyInstaller的安装与pycharm配置支持PyInstaller详细方法
2020/02/27 Python
Django中FilePathField字段的用法
2020/05/21 Python
Scrapy-Redis之RedisSpider与RedisCrawlSpider详解
2020/11/18 Python
HTML5实现获取地理位置信息并定位功能
2015/04/25 HTML / CSS
巴西最大的体育用品商城:Netshoes巴西
2016/11/29 全球购物
美国最大的在线水培用品商店:GrowersHouse.com
2018/08/14 全球购物
意大利奢侈品零售商:ilDuomo Novara
2019/09/11 全球购物
大学生职业规划论文
2014/01/11 职场文书
施工安全协议书范本
2014/09/26 职场文书
网络销售员岗位职责
2015/04/11 职场文书
个人的事迹材料怎么写
2019/04/24 职场文书
写作技巧:优秀文案必备的3种结构
2019/08/19 职场文书
浅析MongoDB之安全认证
2021/06/26 MongoDB
Python按顺序遍历并读取文件夹中文件
2022/04/29 Python
SpringBoot Http远程调用的方法
2022/08/14 Java/Android