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

2025-05-27 0 84

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

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

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

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

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

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

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

PHP计数排序算法的实现代码示例如下:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

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

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40
<?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)
同时,因为要统计出现次数,如果数据范围过大而数据又很稀疏,造成的空间浪费比较大

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

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

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

快网idc优惠网 建站教程 php计数排序算法的实现代码(附四个实例代码) https://www.kuaiidc.com/70553.html

相关文章

发表评论
暂无评论