azhedashuaibi 2019-06-28
计数排序不是基于比较的排序算法,其核心在于将输入的数据值转化为键存储在额外开辟的数组空间中。 作为一种线性时间复杂度的排序,计数排序要求输入的数据必须是有确定范围的整数。
找出待排序的数组中最大和最小的元素; 统计数组中每个值为i的元素出现的次数,存入数组C的第i项; 对所有的计数累加(从C中的第一个元素开始,每一项和前一项相加); 反向填充目标数组:将每个元素i放在新数组的第C(i)项,每放一个元素就将C(i)减去1。
/** * 计数排序: 桶排序的一种 */ $arr = [5,69,4,32,14,8,74,95,23,56,41,5,31,63]; $length = count($arr); $maxValue = $arr[0]; // 找出数组中的最大值 for ($i=1; $i < $length; $i++) { if ($arr[$i] > $maxValue) { $maxValue = $arr[$i]; } } /** * 定长数组, 键会自动排序, PHP数组是hash表的实现, * 如果这里用普通的数组, 键不会自动排序, 不存在的键也不会自动填充null */ $frequency = new SplFixedArray($maxValue + 1); /** * 统计arr中, 值出现的频次 */ for ($i=0; $i < $length; $i++) { if(empty($frequency[$arr[$i]])) $frequency[$arr[$i]] = 0; $frequency[$arr[$i]] += 1; } // 清空$arr $arr = []; // 遍历frequency, 如果其元素有值, 那么将键push到arr中 for ($i=0; $i < count($frequency); $i++) { if (!empty($frequency[$i])) { for ($j=0; $j < $frequency[$i]; $j++) { $arr[] = $i; } } } print_r($arr);