计数排序 php,php计数排序算法的实现代码(附四个实例代码)

计数排序只适合使用在键的变化不大于元素总数的情况下。它通常用作另一种排序算法(基数排序)的子程序,这样可以有效地处理更大的键。

总之,计数排序是一种稳定的线性时间排序算法。计数排序使用一个额外的数组C ,其中第i个元素是待排序数组 A中值等于 i的元素的个数。然后根据数组C 来将A中的元素排到正确的位置。

通常计数排序算法的实现步骤思路是:

1.找出待排序的数组中最大和最小的元素;

2.统计数组中每个值为i的元素出现的次数,存入数组C的第i项;

3.对所有的计数累加(从C中的第一个元素开始,每一项和前一项相加);

4.反向填充目标数组:将每个元素i放在新数组的第C[i]项,每放一个元素就将C[i]减去1。

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、计数排序只适用于整数在小范围内排序

$arr = [95,94,91,98,99,90,99,93,91,92];

function countSort($arr){

$max = $arr[0];

$min = $arr[0];

for($i=0;$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

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 '

';

var_dump($countSort->sort());

输出

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计数排序内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值