1 <?php 2 #基數排序,此處僅對正整數進行排序,至於負數和浮點數,需要用到補碼,各位有興趣自行研究 3 4 #計數排序 5 #@param $arr 待排序數組 6 #@param $digit_num 根據第幾位元進行排序 7 function counting_sort(&$arr, $digit_num = false) { 8 if ($digit_num !== false) { #如果參數$digit_num不為空白,則根據元素的第$digit_num位元進行排序 9 for ($i = 0; $i < count($arr); $i++) {10 $arr_temp[$i] = get_specific_digit($arr[$i], $digit_num);11 } 12 } else {13 $arr_temp = $arr;14 }15 16 $max = max($arr);17 $time_arr = array(); #儲存元素出現次數的數組18 19 #初始化出現次數數組20 for ($i = 0; $i <= $max; $i++) {21 $time_arr[$i] = 0;22 }23 24 #統計每個元素出現次數25 for ($i = 0; $i < count($arr_temp); $i++) {26 $time_arr[$arr_temp[$i]]++;27 }28 29 #統計每個元素比其小或相等的元素出現次數30 for ($i = 0; $i < count($time_arr) - 1; $i++) {31 $time_arr[$i + 1] += $time_arr[$i];32 }33 34 #利用出現次數對數組進行排序35 for($i = count($arr) - 1; $i >= 0; $i--) {36 $sorted_arr[$time_arr[$arr_temp[$i]] - 1] = $arr[$i];37 $time_arr[$arr_temp[$i]]--;38 }39 40 $arr = $sorted_arr;41 ksort($arr); #忽略這次對key排序的效率損耗42 }43 44 #計算某個數的位元45 function get_digit($number) {46 $i = 1;47 while ($number >= pow(10, $i)) {48 $i++;49 }50 51 return $i;52 }53 54 #擷取某個數位從個位算起的第i位元55 function get_specific_digit($num, $i) {56 if ($num < pow(10, $i - 1)) {57 return 0;58 }59 return floor($num % pow(10, $i) / pow(10, $i - 1));60 }61 62 #基數排序,以計數排序作為子排序過程63 function radix_sort(&$arr) {64 #先求出數組中最大的位元65 $max = max($arr);66 $max_digit = get_digit($max);67 68 for ($i = 1; $i <= $max_digit; $i++) {69 counting_sort($arr, $i);70 } 71 }72 73 74 $arr = array(1, 33, 44, 33, 33, 21, 521, 5, 4444, 91, 700, 8, 0);75 radix_sort($arr);76 77 print_r($arr);78 ?>
Array ( [0] => 0 [1] => 1 [2] => 5 [3] => 8 [4] => 21 [5] => 33 [6] => 33 [7] => 33 [8] => 44 [9] => 91 [10] => 521 [11] => 700 [12] => 4444 )