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二维数组的去重问题解析
Jul 17 PHP
url decode problem 解决方法
Dec 26 PHP
PHP常用函数和常见疑难问题解答
Mar 05 PHP
不使用php api函数实现数组的交换排序示例
Apr 13 PHP
destoon网站转移服务器后搜索汉字出现乱码的解决方法
Jun 21 PHP
php实现redis数据库指定库号迁移的方法
Jan 14 PHP
yii2使用ajax返回json的实现方法
May 14 PHP
PHP生成制作验证码的简单实例
Jun 12 PHP
PHP微信开发之根据用户回复关键词\位置返回附近信息
Jun 24 PHP
Yii框架用户登录session丢失问题解决方法
Jan 07 PHP
[原创]php使用strpos判断字符串中数字类型子字符串出错的解决方法
Apr 01 PHP
PHP实现基于面向对象的mysqli扩展库增删改查操作工具类
Jul 18 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
使用PHPExcel导出Excel表
2018/09/08 PHP
PHP进阶学习之垃圾回收机制详解
2019/06/18 PHP
TP5框架model常见操作示例小结【增删改查、聚合、时间戳、软删除等】
2020/04/05 PHP
JavaScript多线程的实现方法
2007/05/08 Javascript
高效的表格行背景隔行变色及选定高亮的JS代码
2010/12/04 Javascript
jQuery Animation实现CSS3动画示例介绍
2013/08/14 Javascript
js获取UserControl内容为拼html时提供方便
2014/11/02 Javascript
js鼠标点击按钮切换图片-图片自动切换-点击左右按钮切换特效代码
2015/09/02 Javascript
jquery Banner轮播选项卡
2016/12/26 Javascript
BootStrap实现轮播图效果(收藏)
2016/12/30 Javascript
详解vue 模拟后台数据(加载本地json文件)调试
2017/08/25 Javascript
vue实现图书管理demo详解
2017/10/17 Javascript
浅谈Angular HttpClient简单入门
2018/05/04 Javascript
vue中,在本地缓存中读写数据的方法
2018/09/21 Javascript
实现Vue的markdown文档可以在线运行的方法示例
2018/12/11 Javascript
Vuex的actions属性的具体使用
2019/04/14 Javascript
对vuex中getters计算过滤操作详解
2019/11/06 Javascript
vue+Element-ui实现登录注册表单
2020/11/17 Javascript
python常见的格式化输出小结
2016/12/15 Python
python中使用正则表达式的连接符示例代码
2017/10/10 Python
利用pyuic5将ui文件转换为py文件的方法
2019/06/19 Python
python中有关时间日期格式转换问题
2019/12/25 Python
Python有参函数使用代码实例
2020/01/06 Python
Python第三方库的几种安装方式(小结)
2020/04/03 Python
Python填充任意颜色,不同算法时间差异分析说明
2020/05/16 Python
python list的index()和find()的实现
2020/11/16 Python
TensorFlow低版本代码自动升级为1.0版本
2021/02/20 Python
pycharm Tab键设置成4个空格的操作
2021/02/26 Python
HTML5实现晶莹剔透的雨滴特效
2014/05/14 HTML / CSS
企业面试题试卷附带答案
2015/12/20 面试题
《草原》教学反思
2014/02/15 职场文书
文明餐桌行动实施方案
2014/02/19 职场文书
装修设计师求职信
2014/02/26 职场文书
幼儿园标语大全
2014/06/19 职场文书
外贸会计专业自荐信
2014/06/22 职场文书
React实现动效弹窗组件
2021/06/21 Javascript