【算法系列】有趣的计数排序

news/2025/2/27 15:02:06/

文章目录

  • 计数排序(Counting Sort)详解
    • 一、基本思想
      • 1. 基本原理
      • 2. 适用场景
      • 3. 稳定性
    • 二、实现步骤
      • 1. 统计频率
      • 2. 累积频率
      • 3. 构建输出数组
      • 4. 复制回原数组
    • 三、代码实现
    • 四、时间复杂度分析
    • 五、空间复杂度分析
    • 六、计数排序的优缺点
    • 七、总结

计数排序(Counting Sort)详解

计数排序(Counting Sort)是一种非比较型排序算法,适用于整数排序。它通过计算每个元素出现的次数来确定它们在输出数组中的位置,从而实现排序。计数排序的时间复杂度为O(n + k),其中n是输入数据的数量,k是输入数据的范围大小。由于其线性时间复杂度,计数排序在处理特定类型的数据时非常高效。

本文将详细介绍计数排序的基本思想、实现步骤、代码示例以及其优缺点。

一、基本思想

1. 基本原理

计数排序的核心思想是通过统计每个元素出现的次数来确定它们在输出数组中的位置。具体步骤如下:

  1. 统计频率:遍历输入数组,统计每个元素出现的次数。
  2. 累积频率:计算累积频率,即每个元素在输出数组中的最终位置。
  3. 构建输出数组:根据累积频率,将输入数组中的元素放置到输出数组的正确位置。
    在这里插入图片描述

2. 适用场景

计数排序特别适用于以下场景:

  • 输入数据为整数且范围较小。
  • 数据分布较为集中,不会出现极端的大或小值。
  • 需要稳定的排序算法(即相同值的相对顺序保持不变)。

3. 稳定性

计数排序是一种稳定排序算法,这意味着具有相同值的元素在排序后的相对顺序与排序前相同。这在某些应用场景中非常重要,例如按多个键进行排序时。

二、实现步骤

以下是计数排序的一个详细实现步骤:

1. 统计频率

首先,创建一个计数数组count[],用于存储每个元素出现的次数。假设输入数据的范围是从0k,则count[]的大小为k + 1

2. 累积频率

对计数数组进行累积求和,得到每个元素在输出数组中的最终位置。具体来说,count[i]表示小于等于i的所有元素的总数。

3. 构建输出数组

根据累积频率,将输入数组中的元素放置到输出数组的正确位置。为了保证稳定性,我们从后向前遍历输入数组,并根据累积频率确定每个元素的最终位置。

4. 复制回原数组

最后,将输出数组复制回原数组,完成排序。

三、代码实现

以下是计数排序的一个Java实现示例:

java">public static void countingSort(int[] arr) {int max = max(arr);int[] cnt = new int[max + 1];// 统计每个元素出现的次数for (int i = 0; i < arr.length; i++) {cnt[arr[i]] ++;}int index = 0;// 根据统计结果构建排序结果for (int i = 0; i <= max; i++) {while(cnt[i] > 0) {arr[index ++] = i;cnt[i] --;}}
}public static int max(int[] arr) {int max = arr[0];for (int i = 1; i < arr.length; i++) {if(arr[i] > max) {max = arr[i];}}return max;
}

四、时间复杂度分析

计数排序的时间复杂度主要由以下几部分组成:

  1. 统计频率:遍历输入数组,统计每个元素出现的次数,时间复杂度为O(n)。
  2. 累积频率:遍历计数数组,计算累积频率,时间复杂度为O(k)。
  3. 构建输出数组:根据累积频率,将输入数组中的元素放置到输出数组的正确位置,时间复杂度为O(n)。
  4. 复制回原数组:将输出数组复制回原数组,时间复杂度为O(n)。
    综上所述,计数排序的总时间复杂度为O(n + k)。

五、空间复杂度分析

计数排序的空间复杂度主要取决于计数数组的大小,计数数组的大小为k + 1,因此空间复杂度为O(k)

六、计数排序的优缺点

  • 优点:
    1. 高效性:对于特定类型的数据(如整数),计数排序可以在O(n + k)的时间复杂度内完成排序,优于大多数基于比较的排序算法
    2. 稳定性:计数排序是一种稳定的排序算法,即相同值的相对顺序不会改变。
    3. 简单易实现:计数排序的实现相对简单,易于理解和调试。
  • 缺点:
    1. 适用范围有限:计数排序仅适用于整数排序,且数据范围不能过大。如果数据范围过大(即k远大于n),则计数排序的效率会大大降低。
    2. 额外空间需求:计数排序需要额外的空间来进行计数,尤其是在处理大范围数据时,可能会占用较多内存。

七、总结

计数排序是一种高效的非比较型排序算法,特别适用于处理整数且范围较小的数据集。通过统计每个元素出现的次数并使用累积频率来确定它们在输出数组中的位置,计数排序能够在O(n + k)的时间复杂度内完成排序任务。尽管其适用范围有限,但在特定场景下,计数排序能够提供显著的性能优势。


http://www.ppmy.cn/news/1575269.html

相关文章

技术改变生活新趋势

人工智能在客户服务中越来越重要。企业用它来提升服务效率和质量。 人工智能可以快速处理大量客户咨询。比如&#xff0c;通过聊天机器人&#xff0c;客户能在任何时间得到即时回复。这不仅节省了客户等待的时间&#xff0c;也减轻了客服人员的压力。 在一些大公司&#xff0…

【excel】easy excel如何导出动态列

动态也有多重含义&#xff1a;本文将描述两种动态场景下的解决方案 场景一&#xff1a;例如表头第一列固定为动物&#xff0c;且必定有第二列&#xff0c;第二列的表头可能为猫 也可能为狗&#xff1b;这是列数固定&#xff0c;列名不固定的场景&#xff1b; 场景二&#xff…

C语言实现单链表

单链表是数据结构中最基础的链式结构,它不按照线性的顺序存储数据,而是由若干个同一结构类型的“节点”依次串联而成的,即每一个节点里保存着下一个节点的地址(指针)。 上图中,一个表头变量head是用来存储链表首节点的地址,链表中每个节点有data(数据)部分和n…

渗透小记--Docker Registry未授权访问

在俺的日常工作中&#xff0c;发现了一处有意思的漏洞&#xff0c;所以在此做一个记录。但是我不想泄露公司秘密&#xff0c;不想吃牢饭&#xff0c;所以只能以比较抽象的方式来记录过程了&#xff0c;望各位见谅。 自动操作手法 nmap就能很好的发现&#xff0c;但是俺是…

ollama 提供给外部访问

ollama外部访问 1、修改ollama配置2、增加配置3、重启ollama4、postMan访问效果 1、修改ollama配置 sudo vim /etc/systemd/system/ollama.service2、增加配置 OLLAMA_HOST 绑定的主机与端口 (默认 “127.0.0.1:11434”) OLLAMA_ORIGINS 允许的源的逗号分隔列表 OLLAMA_MODELS…

探索浮点数在内存中的存储(附带快速计算补码转十进制)

目录 一、浮点数在内存中的存储 1、常见的浮点数&#xff1a; 2、浮点数存储规则&#xff1a; 3、内存中无法精确存储&#xff1a; 4、移码与指数位E&#xff1a; 5、指数E的三种情况&#xff1a; 二、快速计算补码转十进制 1、第一种方法讨论&#xff1a; 2、第二种方…

九、数据治理架构流程

一、总体结构 《数据治理架构流程图》&#xff08;Data Governance Architecture Flowchart&#xff09; 水平结构&#xff1a;流程图采用水平组织&#xff0c;显示从数据源到数据应用的进程。 垂直结构&#xff1a;每个水平部分进一步划分为垂直列&#xff0c;代表数据治理的…

【算法系列】归并排序详解

文章目录 归并排序详解1. 基本原理1.1 分治法策略1.2 归并排序步骤1.3 图解示例 2. 时间复杂度与空间复杂度2.1 时间复杂度2.2 空间复杂度 3. 稳定性4. Java 实现示例5. 归并排序的优点与缺点5.1 优点5.2 缺点 6. 总结 归并排序详解 归并排序&#xff08;Merge Sort&#xff0…