当前位置:首页 > PHP教程 > php应用 > 列表

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

发布:smiling 来源: PHP粉丝网  添加日期:2022-02-23 12:28:47 浏览: 评论:0 

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

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

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

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

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

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

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

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

  1. <?php 
  2. function counting_sort($my_array$min$max
  3.   $count = array(); 
  4.   for($i = $min$i <= $max$i++) 
  5.   { 
  6.     $count[$i] = 0; 
  7.   } 
  8.    
  9.   foreach($my_array as $number
  10.   { 
  11.     $count[$number]++; 
  12.   } 
  13.   $z = 0; 
  14.   for($i = $min$i <= $max$i++) { 
  15.     while$count[$i]-- > 0 ) { 
  16.       $my_array[$z++] = $i
  17.     } 
  18.   } 
  19.   return $my_array
  20. $test_array = array(3, 0, 2, 5, -1, 4, 1); 
  21. echo "原始数组 :\n"
  22. echo implode(', ',$test_array ); 
  23. echo "\n排序后数组\n:"
  24. 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. <?php 
  2. $arr = [95,94,91,98,99,90,99,93,91,92]; 
  3. function countSort($arr){ 
  4. $max = $arr[0]; 
  5. $min = $arr[0]; 
  6. for($i=0;$i<count($arr);$i++){ 
  7. if($arr[$i]>$max){ 
  8. $max = $arr[$i]; 
  9. if($arr[$i] < $min){ 
  10. $min = $arr[$i]; 
  11. try{ 
  12. $frequency = new SplFixedArray($max-$min+1); 
  13. for($i=0;$i<count($arr);$i++){ 
  14. if(emptyempty($frequency[$arr[$i]-$min])) 
  15. $frequency[$arr[$i]-$min] = 0; 
  16. $frequency[$arr[$i]-$min] += 1; 
  17.  
  18. $sum = 0; 
  19. for ($i=0; $i < count($frequency); $i++) { 
  20. $sum += $frequency[$i]; 
  21. $frequency[$i] = $sum
  22.  
  23. $splfixed = new SplFixedArray(count($arr)); 
  24.  
  25. for($i=(count($arr)-1);$i>=0;$i--){ 
  26. $splfixed[$frequency[$arr[$i]-$min]-1] = $arr[$i]; 
  27. $frequency[$arr[$i]-$min] -= 1; 
  28. }catch(RuntimeException $re){ 
  29. echo "RuntimeException: ".$re->getMessage()."\n"
  30. print_r($splfixed->toArray()); 
  31. countSort($arr); 
  32. ?> 

输出

  1. Array 
  2.     [0] => 90 
  3.     [1] => 91 
  4.     [2] => 91 
  5.     [3] => 92 
  6.     [4] => 93 
  7.     [5] => 94 
  8.     [6] => 95 
  9.     [7] => 98 
  10.     [8] => 99 
  11.     [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. class CountSort 
  2.   private $originalData = []; 
  3.   private $rangeMap = []; 
  4.   private $resultData = []; 
  5.  
  6.   public function __construct($original = []) 
  7.   { 
  8.     $this->originalData = $original
  9.   } 
  10.  
  11.   public function sort() 
  12.   { 
  13.     list($min$max) = $this->calculateDataRange(); 
  14.     $this->statisticNumberOfOccurrence($min$max); 
  15.     $this->resultData = $this->generateResult(); 
  16.     return $this->resultData; 
  17.   } 
  18.  
  19.   protected function calculateDataRange() 
  20.   { 
  21.     $max = null; 
  22.     $min = null; 
  23.  
  24.     foreach ($this->originalData as $value) { 
  25.       if (!is_null($max)) { 
  26.         if ($value > $max) { 
  27.           $max = $value
  28.         } 
  29.       } else { 
  30.         $max = $value
  31.       } 
  32.  
  33.       if (!is_null($min)) { 
  34.         if ($value < $min) { 
  35.           $min = $value
  36.         } 
  37.       } else { 
  38.         $min = $value
  39.       } 
  40.     } 
  41.  
  42.     return [$min$max]; 
  43.   } 
  44.  
  45.   protected function statisticNumberOfOccurrence($min$max
  46.   { 
  47.     for ($i = $min$i <= $max$i++) { 
  48.       $this->rangeMap[$i] = 0; 
  49.     } 
  50.  
  51.     foreach ($this->originalData as $value) { 
  52.       $this->rangeMap[$value]++; 
  53.     } 
  54.   } 
  55.  
  56.   protected function generateResult() 
  57.   { 
  58.     $result = []; 
  59.  
  60.     foreach ($this->rangeMap as $key => $value) { 
  61.       if ($value != 0) { 
  62.         for ($i = 0; $i < $value$i++) { 
  63.           array_push($result$key); 
  64.         } 
  65.       } 
  66.     } 
  67.     return $result
  68.   } 
  69.  
  70. $testData = [2, 3, 4, 3, 10, 30, 20, 15, 10, 12, 33]; 
  71.  
  72. $countSort = new CountSort($testData); 
  73. echo '<pre>'
  74. var_dump($countSort->sort()); 

输出

  1. <pre>array(11) { 
  2.   [0]=> 
  3.   int(2) 
  4.   [1]=> 
  5.   int(3) 
  6.   [2]=> 
  7.   int(3) 
  8.   [3]=> 
  9.   int(4) 
  10.   [4]=> 
  11.   int(10) 
  12.   [5]=> 
  13.   int(10) 
  14.   [6]=> 
  15.   int(12) 
  16.   [7]=> 
  17.   int(15) 
  18.   [8]=> 
  19.   int(20) 
  20.   [9]=> 
  21.   int(30) 
  22.   [10]=> 
  23.   int(33) 
  24. }

Tags: php计数排序算法

分享到: