教程 sort tutorial

计数排序(Counting Sort)

计数排序是一种非比较类排序算法,适用于整数且范围不大的数组。它通过统计每个数出现的次数,并根据这些统计信息计算出每个元素的最终位置,从而实现排序。

该算法的时间复杂度为 O(n + k),其中 n 是元素数量,k 是值域范围大小。

📌 算法原理解释

计数排序流程如下:

  1. 找出待排序数组中的最大值 max;
  2. 创建一个长度为 max + 1 的计数数组 count,统计每个元素出现的次数;
  3. 将 count 数组变为前缀和数组,表示元素在排序后应出现的位置;
  4. 倒序遍历原数组,将每个元素放到结果数组中的正确位置(可保持稳定性);
  5. 返回结果数组。

⚠️ 注意事项:

  • 不适用于小数、负数(需额外处理);
  • 适合范围有限的非负整数排序,如考试成绩、年龄等。

💻 多语言代码实现

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 等。