计数排序(Counting Sort)详解

简介: 计数排序(Counting Sort)是一种非比较排序算法,其核心思想是通过计数每个元素的出现次数来进行排序,适用于整数或有限范围内的非负整数排序。这个算法的特点是速度快且稳定,适用于某些特定场景。在本文中,我们将深入探讨计数排序的原理、步骤以及性能分析。

计数排序(Counting Sort)是一种非比较排序算法,其核心思想是通过计数每个元素的出现次数来进行排序,适用于整数或有限范围内的非负整数排序。这个算法的特点是速度快且稳定,适用于某些特定场景。在本文中,我们将深入探讨计数排序的原理、步骤以及性能分析。

countingSort.jpg

算法原理

计数排序的基本思想是:

  1. 计数: 遍历待排序的数组,统计每个元素出现的次数,并将统计结果存储在一个计数数组中。计数数组的索引对应着元素的值,而计数数组中的值表示该元素出现的次数。

  2. 累积计数: 对计数数组进行累积计数,即将每个元素的计数值加上前一个元素的计数值,得到每个元素在排序后数组中的位置。这一步确保相同元素的相对顺序不变。

  3. 排序: 创建一个与待排序数组大小相同的结果数组,然后遍历待排序数组,根据元素的值在累积计数数组中找到其在结果数组中的位置,将元素放置在结果数组中的正确位置。

算法步骤

计数排序的具体步骤如下:

  1. 扫描待排序数组,确定数组的最大值(max)和最小值(min)。

  2. 创建一个计数数组(count),长度为max - min + 1。

  3. 第一次遍历待排序数组,统计每个元素出现的次数,将结果存储在计数数组中。

  4. 对计数数组进行累积计数,确保计数数组中的每个元素表示小于等于该元素值的元素个数。

  5. 创建一个与待排序数组大小相同的结果数组(result)。

  6. 第二次遍历待排序数组,根据元素的值在累积计数数组中找到其在结果数组中的位置,将元素放置在结果数组中的正确位置。

  7. 将结果数组复制回原始数组,完成排序。

Java 实现

以下是使用Java语言实现计数排序算法的示例代码:

public class Test {

    public static void main(String[] args) {
        int[] arr = new int[]{5,2,3,1,6,7,1,3};
        countingSort(arr);
    }

    public static void countingSort(int[] arr){
        System.out.println("原始数组:"+ Arrays.toString(arr));
        //获取排序数组的长度
        int len=  arr.length;
        //获取数组最大元素
        int max = Arrays.stream(arr).max().getAsInt();
        //获取数组最小元素
        int min = Arrays.stream(arr).min().getAsInt();
        //计算计数数组的长度
        int rang = max-min+1;
        //创建计数数组
        int count[] = new int[rang];
        //创建排序后的目标数组
        int result[] = new int[len];
        //计数:统计每个元素出现的次数
        for(int i = 0; i < len; i++){
            count[arr[i]-min]++;
        }
        System.out.println("计数数组:"+ Arrays.toString(count));
        //累计计数:计算每个元素在排序后数组中的位置
        for(int j = 1 ;j < rang; j++){
            count[j]+=count[j-1];
        }
        System.out.println("累计计数数组:"+ Arrays.toString(count));
        //排序:根据累计计数数组将元素放置到正确的位置
        for(int k = len -1 ; k >= 0; k--){
            result[count[arr[k] - min] -1] = arr[k];
            count[arr[k] - min]--;
        }
        System.arraycopy(result, 0, arr, 0, len);
        System.out.println("排序完成的数组:"+ Arrays.toString(arr));
    }
}

运行结果为:

原始数组:[5, 2, 3, 1, 6, 7, 1, 3]
计数数组:[2, 1, 2, 0, 1, 1, 1]
累计计数数组:[2, 3, 5, 5, 6, 7, 8]
排序完成的数组:[1, 1, 2, 3, 3, 5, 6, 7]

这段代码演示了如何使用计数排序算法对整数数组进行排序。计数排序是一种稳定的排序算法,适用于整数范围不大的情况,它的时间复杂度为O(n + k),其中n是待排序数组的大小,k是整数范围(数组中最大元素与最小元素的差值)。

性能分析

计数排序的性能分析如下:

  • 平均时间复杂度:O(n + k),其中n是待排序数组的大小,k是整数范围。

  • 最坏时间复杂度:O(n + k)。

  • 最佳时间复杂度:O(n + k)。

  • 空间复杂度:O(n + k),需要额外的计数数组和结果数组。

  • 稳定性:计数排序是一种稳定的排序算法,不改变相同元素的相对顺序。

使用场景

计数排序适用于以下情况:

  • 需要排序的数据是整数或有限范围内的非负整数。

  • 待排序数据中存在大量重复元素。

  • 对稳定性排序有要求,即相同元素的相对顺序不变。

总结

计数排序是一种高效的非比较排序算法,适用于整数排序和稳定性排序的场景。尽管它对整数范围有一定要求,但在合适的情况下,计数排序能够提供线性时间复杂度的排序性能,相对于其他复杂排序算法来说,它具有独特的优势。因此,在选择排序算法时,应根据数据特点和性能需求来决定是否使用计数排序。

目录
相关文章
|
7月前
|
人工智能 搜索推荐 算法
sort-04-heap sort 堆排序算法详解
这是一个关于排序算法的系列文章摘要,包括了10篇关于不同排序算法的链接,如冒泡排序、快速排序、选择排序、堆排序等。堆排序是一种基于比较的排序算法,利用了近似完全二叉树的结构并满足最大堆或最小堆的性质。最大堆中,每个节点的值都大于或等于其子节点。文章详细解释了最大堆的概念、节点访问方式以及堆的操作,包括堆调整和堆排序的过程,并通过图解展示了堆排序的具体步骤。此外,还提供了一个Java实现的堆排序代码示例。整个排序系列来源于一个开源项目,读者可以通过链接查看完整内容。
sort-04-heap sort 堆排序算法详解
|
7月前
|
搜索推荐 算法 Java
sort-08-counting sort 计数排序
这是一个关于排序算法的系列文章摘要。文章详细介绍了多种排序算法,包括冒泡排序、快速排序、选择排序、堆排序、插入排序、希尔排序、归并排序、计数排序、桶排序以及大文件外部排序。计数排序是一种线性时间复杂度的稳定排序算法,由 Harold H. Seward 在1954年提出。基础版计数排序通过创建一个与最大元素等长的新数组来统计每个元素出现的次数,然后填充排序结果。改良版则考虑了空间浪费问题,通过找出最小值来减少数组长度。此外,还提出了使用 TreeMap 来扩展排序算法以适应非数字元素的情况。
|
存储 算法 Java
基数排序详解(Radix sort)
基数排序详解(Radix sort)
124 0
|
7月前
|
搜索推荐 Python
堆排序(Heap Sort)
堆排序(Heap Sort)是一种选择排序算法,通过将待排序的元素构建成一个最大堆(或最小堆),然后将堆顶元素与堆尾元素交换,将堆的大小减一,再调整堆,使其重新满足最大堆(或最小堆)的性质。重复以上步骤,直到堆中只剩下一个元素,即排序完成。
40 2
|
搜索推荐 JavaScript 前端开发
基数排序(Radix Sort)
基数排序(Radix Sort)是一种非比较排序算法,它根据数字的每一位(从最低位到最高位)进行排序,具体来说,它是将所有待排序的数字统一为同样的数位长度,然后从最低位开始,依次对每个数位进行排序,最后将所有数字按照数位从低到高的顺序合并成一个有序数组。
85 6
|
算法 搜索推荐
经典算法之折半插入排序(Binary Insertion Sort)
经典算法之折半插入排序(Binary Insertion Sort)
340 0
2-路插入排序(Two-Way Insertion Sort)
算法介绍 算法描述 算法分析 代码实现 参考
|
算法 搜索推荐 Java
|
搜索推荐 算法 数据可视化
【基础篇】9 # 排序:冒泡排序(Bubble Sort)、插入排序(Insertion Sort)、选择排序(Selection Sort)
【基础篇】9 # 排序:冒泡排序(Bubble Sort)、插入排序(Insertion Sort)、选择排序(Selection Sort)
120 0
【基础篇】9 # 排序:冒泡排序(Bubble Sort)、插入排序(Insertion Sort)、选择排序(Selection Sort)