计数排序(Counting Sort)
计数排序是一种非比较类排序算法,适用于整数且范围不大的数组。它通过统计每个数出现的次数,并根据这些统计信息计算出每个元素的最终位置,从而实现排序。
该算法的时间复杂度为 O(n + k),其中 n 是元素数量,k 是值域范围大小。
📌 算法原理解释
计数排序流程如下:
- 找出待排序数组中的最大值 max;
- 创建一个长度为 max + 1 的计数数组 count,统计每个元素出现的次数;
- 将 count 数组变为前缀和数组,表示元素在排序后应出现的位置;
- 倒序遍历原数组,将每个元素放到结果数组中的正确位置(可保持稳定性);
- 返回结果数组。
⚠️ 注意事项:
- 不适用于小数、负数(需额外处理);
- 适合范围有限的非负整数排序,如考试成绩、年龄等。
💻 多语言代码实现
// 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 计数排序
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
// 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 计数排序
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 计数排序
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 计数排序
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 等。
相关内容
- 冒泡排序(Bubble Sort) 冒泡排序是一种基础且易懂的排序算法,适合小规模数据排序。本文提供冒泡排序的算法原理与 JavaScript、Python、C++、Java、PHP、Go 多语言...
- 基数排序(Radix Sort) 基数排序是一种非比较类排序,适用于整数或定长字符串。本文介绍 LSD 方式的基数排序算法,提供 JavaScript、Python、C++、Java、PHP、G...
- 选择排序(Selection Sort) 选择排序是一种简单直观的排序算法,通过反复选择最小元素放到前面实现排序。本文讲解算法原理,并提供 JavaScript、Python、C++、Java、PHP、...
- 插入排序(Insertion Sort) 插入排序是一种简单且高效的排序算法,适合部分有序数组排序。本文介绍算法原理,并提供 JavaScript、Python、C++、Java、PHP、Go 多语言示...
- 希尔排序(Shell Sort) 介绍希尔排序的原理和分组插入策略,适用于中等规模数据。附带 JavaScript、Python、C++、Java、PHP、Go 多语言实现代码,助你深入理解。
- 归并排序(Merge Sort) 介绍归并排序的分治法思想、稳定性特点和适用场景,附带 JavaScript、Python、C++、Java、PHP、Go 多语言实现及详细解析,帮助深入理解。