1. 程式人生 > >PHP 計數排序 ,適用與範圍內排序

PHP 計數排序 ,適用與範圍內排序

<?php
// 計數排序演算法
# 適用於一定範圍內的排序
function countSort ($arr) {
	$count = count($arr);
	# 獲取最大的元素max、min
	$max = $min = $arr[0];
	# 範圍為min ~ max 構建統計陣列  
	$new = [];
	# 便利陣列填充 統計陣列
	for ($j = 0; $j < $count; $j++) { 
		if ($arr[$j] > $max) {
			$max = $arr[$j];
		}
		if ($arr[$j] < $min) {
			$min = $arr[$j];
		}
		if (isset($new[ $arr[$j] ])) {
			$new[$arr[$j]]++;
		}else {
			$new[$arr[$j]] = 1;
		}
	}
	# 便利陣列輸出結果
	$str = [];
	for ($k = $min; $k <= $max; $k++) { 
		if ($new[$k] == 0) {
			continue;
		}
		// echo $new[$k] . "\n";
		$n = 0;
		while ($n <= $new[$k] - 1) {
			$n++;
			array_push($str, $k);
		}
	}
	return $str;
}

$arr = [4,4,6,5,3,2,8,1,7,5,6,0,10,9,4,6,3];
$res = countSort($arr);
print_r(implode(",", $res)); 
echo "\n";

// 優化 (針對重複值。穩定排序)
function newCountSort($arr) {
	$count = count($arr);
	# 獲取最大、最小元素max、min
	$max = $min = $arr[0];
	for ($i = 0; $i < $count; $i++) { 
		if ($arr[$i] > $max) {
			$max = $arr[$i];
		}
		if ($arr[$i] < $min) {
			$min = $arr[$i];
		}
	}
	// echo $max . "\t" . $min . "\n";die;
	# 獲取差值
	$difference = $max - $min;
	# 建立統計陣列並統計對應元素個數(如果不減?預設已原值做鍵值)
	$new = [];
	for ($j = 0; $j < $count; $j++) { 
		if (isset($new[$arr[$j] - $min])) {
			$new[$arr[$j] - $min]++;
		}else {
			$new[$arr[$j] - $min] = 1;
		}
		
	}
	# 統計陣列做變形,後面的元素等於前面的元素之和
	$sum = 0;
	for ($i = 0; $i <= $difference ; $i++) { 
		if(!isset($new[$i])) {
			continue;
		} 
		$sum += $new[$i];
		$new[$i] = $sum;
	}
	# 倒序遍歷原始數列,從統計陣列找到正確位置,輸出到結果陣列
	$sort_arr = [];
	for ($j = $count - 1; $j >= 0; $j--) { 
		$sort_arr[$new[$arr[$j] - $min] - 1] = $arr[$j];
		$new[$arr[$j] - $min]--;
	}
	ksort($sort_arr);  // 這裡迴圈輸出結果
	return $sort_arr;
}
$arr = [56,57,53,55,54,50,52,59,51,54];
$res = newCountSort($arr);
print_r(implode(",", $res)); 
echo "\n";