主题
计数排序(Counting Sort)
计数排序是一种非比较类排序算法,适用于整数且范围不大的数组。它通过统计每个数出现的次数,并根据这些统计信息计算出每个元素的最终位置,从而实现排序。
该算法的时间复杂度为 O(n + k),其中 n 是元素数量,k 是值域范围大小。
📌 算法原理解释
计数排序流程如下:
- 找出待排序数组中的最大值 max;
- 创建一个长度为 max + 1 的计数数组 count,统计每个元素出现的次数;
- 将 count 数组变为前缀和数组,表示元素在排序后应出现的位置;
- 倒序遍历原数组,将每个元素放到结果数组中的正确位置(可保持稳定性);
- 返回结果数组。
⚠️ 注意事项:
- 不适用于小数、负数(需额外处理);
- 适合范围有限的非负整数排序,如考试成绩、年龄等。
💻 多语言代码实现
javascript
// JavaScript 计数排序
function countingSort(arr) {
if (arr.length === 0) return [];
const max = Math.max(...arr);
const count = new Array(max + 1).fill(0);
const output = new Array(arr.length);
for (let num of arr) count[num]++;
for (let i = 1; i <= max; i++) count[i] += count[i - 1];
for (let i = arr.length - 1; i >= 0; i--) {
const num = arr[i];
output[--count[num]] = num;
}
return output;
}
python
# Python 计数排序
def counting_sort(arr):
if not arr:
return []
max_val = max(arr)
count = [0] * (max_val + 1)
output = [0] * len(arr)
for num in arr:
count[num] += 1
for i in range(1, len(count)):
count[i] += count[i - 1]
for i in range(len(arr) - 1, -1, -1):
output[count[arr[i]] - 1] = arr[i]
count[arr[i]] -= 1
return output
cpp
// C++ 计数排序
#include <vector>
using namespace std;
vector<int> countingSort(const vector<int>& arr) {
if (arr.empty()) return {};
int maxVal = *max_element(arr.begin(), arr.end());
vector<int> count(maxVal + 1, 0), output(arr.size());
for (int num : arr) count[num]++;
for (int i = 1; i <= maxVal; i++) count[i] += count[i - 1];
for (int i = arr.size() - 1; i >= 0; i--) {
output[--count[arr[i]]] = arr[i];
}
return output;
}
java
// Java 计数排序
public class CountingSort {
public static int[] countingSort(int[] arr) {
if (arr.length == 0) return arr;
int max = arr[0];
for (int num : arr) max = Math.max(max, num);
int[] count = new int[max + 1];
int[] output = new int[arr.length];
for (int num : arr) count[num]++;
for (int i = 1; i < count.length; i++) count[i] += count[i - 1];
for (int i = arr.length - 1; i >= 0; i--) {
output[--count[arr[i]]] = arr[i];
}
return output;
}
}
php
<?php
// PHP 计数排序
function countingSort(array $arr): array {
if (empty($arr)) return [];
$max = max($arr);
$count = array_fill(0, $max + 1, 0);
$output = array_fill(0, count($arr), 0);
foreach ($arr as $num) $count[$num]++;
for ($i = 1; $i <= $max; $i++) $count[$i] += $count[$i - 1];
for ($i = count($arr) - 1; $i >= 0; $i--) {
$output[--$count[$arr[$i]]] = $arr[$i];
}
return $output;
}
?>
go
// Go 计数排序
package main
func countingSort(arr []int) []int {
if len(arr) == 0 {
return []int{}
}
max := arr[0]
for _, v := range arr {
if v > max {
max = v
}
}
count := make([]int, max+1)
output := make([]int, len(arr))
for _, v := range arr {
count[v]++
}
for i := 1; i <= max; i++ {
count[i] += count[i-1]
}
for i := len(arr) - 1; i >= 0; i-- {
output[count[arr[i]]-1] = arr[i]
count[arr[i]]--
}
return output
}
✅ 算法特点与总结
属性 | 描述 |
---|---|
时间复杂度 | O(n + k) |
空间复杂度 | O(k)(用于计数数组) |
稳定性 | ✅ 稳定 |
是否原地排序 | ❌ 否(需额外数组) |
适用条件 | 元素为非负整数且范围不大 |
📌 提示:计数排序适用于整数、离散且范围较小的场景,如年龄、分数、ID 等。