admin管理员组

文章数量:1441555

常用的排序算法之计数排序(Counting Sort)

计数排序(Counting Sort)

原理

计数排序(Counting Sort)的起源并不明确指向某一个特定的发明者或时间点,但它作为一种简单直观的排序算法,在计算机科学中得到了广泛的应用。计数排序的基本思想是通过统计数组中每个元素出现的次数,来确定其在排序后数组中的位置。

定义

计数排序是一种非基于比较的排序算法,适用于一定范围内的整数排序。它将输入的数据值转化为键存储在额外开辟的数组空间中。作为一种线性时间复杂度的排序,计数排序要求输入的数据必须是有确定范围的整数。

引伸义

计数排序的主要思想是通过“计数”来排序,即统计每个元素出现的次数,然后根据这个次数来确定元素在排序后数组中的位置。这种方法避免了传统比较排序算法中的重复比较,从而实现了线性的时间复杂度。

优缺点

优点:

  1. 时间复杂度低,为O(n+k)(n为待排序数组长度,k为待排序数组中元素的取值范围)。
  2. 稳定性好,相等的元素在排序后保持原有的相对顺序。
  3. 空间复杂度为O(k),其中k为待排序数组中元素的取值范围。

缺点:

  1. 当k很大时,需要消耗大量空间。
  2. 只适用于整数排序,且要求待排序数组中的元素非负。

使用场景

计数排序适用于待排序数组元素取值范围较小且非负的场景,如考试成绩排序(假设分数范围为0-100)等。

使用数据一步步举例

假设有一个待排序数组arr = [4, 2, 2, 8, 3, 3, 1],其元素取值范围为1-9。

  1. 初始化一个长度为10(取值范围+1)的计数数组count,并将所有元素初始化为0。 count = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
  2. 遍历待排序数组arr,统计每个元素出现的次数,并将计数数组对应位置的值加1。 arr: [4, 2, 2, 8, 3, 3, 1] count 变为: [1, 1, 2, 2, 1, 0, 0, 0, 1, 0]
  3. 修改计数数组,使得每个位置的值变为小于等于该值的元素个数。 count 变为: [0, 1, 2, 4, 5, 5, 5, 5, 6, 6]
  4. 从后往前遍历待排序数组arr,将每个元素放到排序后数组sortedArrcount[arr[i]]-1位置,并更新count[arr[i]]的值。 sortedArr = [] for i from len(arr) - 1 to 0: sortedArr.insert(count[arr[i]] - 1, arr[i]) count[arr[i]] -= 1 排序后的数组sortedArr[1, 2, 2, 3, 3, 4, 8]

Java示例代码

代码语言:javascript代码运行次数:0运行复制
public class CountingSort {  
  
    // 查找数组中的最大值  
    private static int findMaxValue(int[] arr) {  
        int maxValue = arr[0];  
        for (int i = 1; i < arr.length; i++) {  
            if (arr[i] > maxValue) {  
                maxValue = arr[i];  
            }  
        }  
        return maxValue;  
    }  
  
    // 计数排序方法  
    public static void countingSort(int[] arr) {  
        if (arr == null || arr.length == 0) return;  
  
        int maxValue = findMaxValue(arr);  
        int[] count = new int[maxValue + 1];  
  
        // 统计每个元素出现的次数  
        for (int i = 0; i < arr.length; i++) {  
            count[arr[i]]++;  
        }  
  
        // 修改count数组,使得每个位置的值变为小于等于该值的元素个数  
        for (int i = 1; i <= maxValue; i++) {  
            count[i] += count[i - 1];  
        }  
  
        // 从后往前遍历arr,将元素放到正确的位置  
        int[] sortedArr = new int[arr.length];  
        for (int i = arr.length - 1; i >= 0; i--) {  
            sortedArr[count[arr[i]] - 1] = arr[i];  
            count[arr[i]]--;  
        }  
  
        // 将排序后的数组复制回原数组  
        System.arraycopy(sortedArr, 0, arr, 0, arr.length);  
    }  
  
    // 主方法,用于测试计数排序  
    public static void main(String[] args) {  
        int[] arr = {4, 2, 2, 8, 3, 3, 1};  
        System.out.println("Original array: " + Arrays.toString(arr));  
  
        countingSort(arr);  
  
        System.out.println("Sorted array: " + Arrays.toString(arr));  
    }  
}  

  在这段代码中,我添加了一个findMaxValue方法来查找数组中的最大值,以便正确地初始化计数数组count的大小。然后,我添加了一个main方法来测试countingSort方法。main方法创建了一个示例数组,打印出原始数组,调用countingSort方法进行排序,并打印出排序后的数组。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。 原始发表:2024-05-27,如有侵权请联系 cloudcommunity@tencent 删除排序算法数组countingsort排序

本文标签: 常用的排序算法之计数排序(Counting Sort)