Java 计数排序

  1. 概念:计数排序是一种不基于比较的排序算法,主要思想是先计算出待排序序列的最大值 maxValue 与 最小值 minValue,再开辟一个长度为 maxValue - minValue + 1 的额外空间,然后统计待排序序列中每个元素的数量,记录在额外空间中,最后遍历一遍额外空间,按照顺序把每个元素赋值到原始序列中。
  2. 图解
  3. Java 计数排序_第1张图片
  4. 代码

import java.util.Arrays;

public class CountSort {
    // 计数排序,a 是数组,n 是数组大小。假设数组中存储的都是非负整数。
    public static void countingSort(int[] a, int n) {
        if (n <= 1) return;

        // 查找数组中数据的范围
        int max = a[0];
        for (int i = 1; i < n; ++i) {
            if (max < a[i]) {
                max = a[i];
            }
        }

        int[] c = new int[max + 1]; // 申请一个计数数组 c,下标大小 [0,max]
        for (int i = 0; i <= max; ++i) {
            c[i] = 0;
        }

        // 计算每个元素的个数,放入 c 中
        for (int i = 0; i < n; ++i) {
            c[a[i]]++;
        }

        // 依次累加
        for (int i = 1; i <= max; ++i) {
            c[i] = c[i-1] + c[i];
        }

        // 临时数组 r,存储排序之后的结果
        int[] r = new int[n];
        // 计算排序的关键步骤,有点难理解
        for (int i = n - 1; i >= 0; --i) {
            int index = c[a[i]]-1;
            r[index] = a[i];
            c[a[i]]--;
        }

        // 将结果拷贝给 a 数组
        for (int i = 0; i < n; ++i) {
            a[i] = r[i];
        }
    }
    public static void main(String[] args) {
        int[] array = new int[]{3, 4, 2, 1, 5, 6, 7, 8};
        countingSort(array, array.length);
        System.out.println(Arrays.toString(array));
    }
}

复杂度分析和是否稳定

  • 1. 时间复杂度:O(n+k)
    当待排序元素是 n 个 0 到 k 之间的整数时,时间复杂度是 O(n+k) O(n+k)O(n+k)。

    2. 额外空间复杂度:O(n+k)
    计数排序需要两个额外的数组,分别用于记录元素数量与排序结果。

  • 生成排序结果的过程(28行),是从后向前遍历的,也就是说原始数组中先出现的元素依旧会在前面。

    所以,计数排序是稳定的排序算法。

你可能感兴趣的:(数据结构与算法,数据结构与算法,数据结构与算法)