返回

计数排序及基数排序算法的Java实现

后端

上期我们谈了快速排序和希尔排序。本期我们将一起学习计数排序和基数排序算法。

1. 计数排序

计数排序是一种简单有效的排序算法,适用于数据范围较小的情况。其原理是将数据按照其值的大小划分为多个桶,然后将每个桶中的数据依次取出,形成一个有序序列。

1.1 时间复杂度

计数排序的时间复杂度为O(n + k),其中n为数据个数,k为数据范围。

1.2 空间复杂度

计数排序的空间复杂度为O(n + k),其中n为数据个数,k为数据范围。

1.3 代码实现

public static void countingSort(int[] arr) {
    // 找到最大值
    int max = arr[0];
    for (int i = 1; i < arr.length; i++) {
        if (arr[i] > max) {
            max = arr[i];
        }
    }

    // 创建计数数组
    int[] count = new int[max + 1];

    // 统计每个元素出现的次数
    for (int i = 0; i < arr.length; i++) {
        count[arr[i]]++;
    }

    // 将计数数组中的元素累加
    for (int i = 1; i <= max; i++) {
        count[i] += count[i - 1];
    }

    // 根据计数数组中的值重新排列元素
    int[] sortedArr = new int[arr.length];
    for (int i = arr.length - 1; i >= 0; i--) {
        int index = count[arr[i]] - 1;
        sortedArr[index] = arr[i];
        count[arr[i]]--;
    }

    // 将排序后的数组复制回原数组
    for (int i = 0; i < arr.length; i++) {
        arr[i] = sortedArr[i];
    }
}

2. 基数排序

基数排序是一种非比较型排序算法,适用于数据范围较大的情况。其原理是将数据按照其值的大小划分为多个桶,然后将每个桶中的数据依次取出,形成一个有序序列。

2.1 时间复杂度

基数排序的时间复杂度为O(nk),其中n为数据个数,k为数据范围的位数。

2.2 空间复杂度

基数排序的空间复杂度为O(n + k),其中n为数据个数,k为数据范围的位数。

2.3 代码实现

public static void radixSort(int[] arr) {
    // 找到最大值
    int max = arr[0];
    for (int i = 1; i < arr.length; i++) {
        if (arr[i] > max) {
            max = arr[i];
        }
    }

    // 计算数据范围的位数
    int exp = 1;
    while (max / exp > 0) {
        countingSort(arr, exp);
        exp *= 10;
    }
}

public static void countingSort(int[] arr, int exp) {
    // 创建计数数组
    int[] count = new int[10];

    // 统计每个元素出现的次数
    for (int i = 0; i < arr.length; i++) {
        int index = arr[i] / exp % 10;
        count[index]++;
    }

    // 将计数数组中的元素累加
    for (int i = 1; i < count.length; i++) {
        count[i] += count[i - 1];
    }

    // 根据计数数组中的值重新排列元素
    int[] sortedArr = new int[arr.length];
    for (int i = arr.length - 1; i >= 0; i--) {
        int index = count[arr[i] / exp % 10] - 1;
        sortedArr[index] = arr[i];
        count[arr[i] / exp % 10]--;
    }

    // 将排序后的数组复制回原数组
    for (int i = 0; i < arr.length; i++) {
        arr[i] = sortedArr[i];
    }
}

3. 总结

计数排序和基数排序都是简单高效的排序算法,适用于不同的数据情况。计数排序适用于数据范围较小的情况,时间复杂度为O(n + k),其中n为数据个数,k为数据范围。基数排序适用于数据范围较大的情况,时间复杂度为O(nk),其中n为数据个数,k为数据范围的位数。