计数排序算法

embedded/2025/2/3 8:45:08/

基本思想

先确定待排序数组的最大值(Max)和最小值(Min),随后创建Max - Min + 1个长度的数组称为计数数组,计数数组的索引对应着待排序数组中元素的值,数组的值表示该元素的出现次数。通过从前往后或者从后往前遍历数组,用数组下标+Min得到已排序好数组的值。并且累加每个位置的计数,得到每个元素的最终位置。最后依次将元素放回到结果数组中,得到排序后的数组。

示例

假设我们有以下数组需要排序:[4, 2, 2, 8, 3, 3, 1]

1、确定范围:最大值是 8,最小值是 1。
2、创建计数数组:根据最大值和最小值,创建计数数组 C,其长度为 最大值 - 最小值 + 1,即 C[0] 对应数字 1,C[7] 对应数字 8。

C[0] = 0  (表示数字 1 出现次数)
C[1] = 0  (表示数字 2 出现次数)
C[2] = 0  (表示数字 3 出现次数)
C[3] = 0  (表示数字 4 出现次数)
C[4] = 0  (表示数字 5 出现次数)
C[5] = 0  (表示数字 6 出现次数)
C[6] = 0  (表示数字 7 出现次数)
C[7] = 0  (表示数字 8 出现次数)

3、统计每个数字的出现次数

C[0] = 1 (数字 1 出现 1 次)
C[1] = 2 (数字 2 出现 2 次)
C[2] = 2 (数字 3 出现 2 次)
C[3] = 1 (数字 4 出现 1 次)
​​​​​​​C[7] = 1 (数字 8 出现 1 次)

4、累加计数数组:为了确定每个元素的位置,累加每个元素的计数值。
5、将元素放入结果数组:根据累加后的计数数组,将原数组的元素放到排序后的结果数组中。
排序后的结果:[1, 2, 2, 3, 3, 4, 8]
 

复杂度

时间复杂度:O(n + k),其中 n 是待排序数组的元素个数,k 是待排序数组中的最大值和最小值之间的范围(即最大值Max与最小值Min之差)。

如果数组中的元素范围(k)不大,那么计数排序的时间复杂度可以接近 O(n),适合用于范围较小的整数排序。
如果元素范围 k 很大,计数排序的空间和时间复杂度就会受到影响。

空间复杂度:O(n + k),需要额外的空间来存储计数数组和排序后的数组。

稳定性:计数排序是稳定的。

代码实现

public static void countingSort(int[] arr) {// 1. 找到最大值和最小值int max = Integer.MIN_VALUE;int min = Integer.MAX_VALUE;for (int num : arr) {if (num > max) max = num;if (num < min) min = num;}// 2. 创建计数数组int range = max - min + 1;int[] count = new int[range];// 3. 统计每个元素的出现次数for (int num : arr) {count[num - min]++;}// 4. 累加计数数组for (int i = 1; i < count.length; i++) {count[i] += count[i - 1];}// 5. 构造排序后的数组int[] sortedArr2 = new int[arr.length];for (int i = arr.length - 1; i >= 0; i--) {sortedArr2[count[arr[i] - min] - 1] = arr[i];count[arr[i] - min]--;}// 6. 将排序后的数组复制回原数组System.arraycopy(sortedArr, 0, arr, 0, arr.length);}
   这段代码是简化版的累加计数过程,可以代替上段代码的4-5步,适用于重复元素出现过多的情况int[] sortedArr = new int[arr.length];int j = 0;for (int i = 0; i <= arr.length - 1; i++) {while(count[j] == 0){j++;}sortedArr[i] = j + min;count[j]--;}


http://www.ppmy.cn/embedded/159141.html

相关文章

22.Word:小张-经费联审核结算单❗【16】

目录 NO1.2 NO3.4​ NO5.6.7 NO8邮件合并 MS搜狗输入法 NO1.2 用ms打开文件&#xff0c;而不是wps❗不然后面都没分布局→页面设置→页面大小→页面方向→上下左右&#xff1a;页边距→页码范围&#xff1a;多页&#xff1a;拼页光标处于→布局→分隔符&#xff1a;分节符…

08.七种排序算法实现(C语言)

目录 一.排序的基本概念 1.1 排序的概念 1.2 常见的排序算法 二.常见排序算法的实现 2.1 插入排序&#xff08;直接&#xff09; 1.基本思想 2.直接插入排序的特性 3.代码实现 2.2 希尔排序 1.基本思想 2.希尔插入排序的特性 3.代码实现 2.3 选择排序 1.基本思想 2…

DB-GPT试用

继续上一篇 DB-GPT的安装 https://blog.csdn.net/berryreload/article/details/142845190 访问http://xxx:5670 访问这里 创建数据库连接 http://10.168.1.208:5670/construct/database 访问这里&#xff0c;点击刷新 http://10.168.1.208:5670/construct/app 刷新后才能出…

五. Redis 配置内容(详细配置说明)

五. Redis 配置内容(详细配置说明) 文章目录 五. Redis 配置内容(详细配置说明)1. Units 单位配置2. INCLUDES (包含)配置3. NETWORK (网络)配置3.1 bind(配置访问内容)3.2 protected-mode (保护模式)3.3 port(端口)配置3.4 timeout(客户端超时时间)配置3.5 tcp-keepalive()配置…

Java手写简单Merkle树

Java手写Merkle树代码 package com.blockchain.qgy.component;import com.blockchain.qgy.model.MerkleTreeNode; import com.blockchain.qgy.util.SHAUtil;import java.util.*;public class MerkleTree<T> {//merkle树private List<MerkleTreeNode<T>> lis…

论文笔记(六十三)Understanding Diffusion Models: A Unified Perspective(四)

Understanding Diffusion Models: A Unified Perspective&#xff08;四&#xff09; 文章概括学习扩散噪声参数&#xff08;Learning Diffusion Noise Parameters&#xff09;三种等效的解释&#xff08;Three Equivalent Interpretations&#xff09; 文章概括 引用&#xf…

曲线救国——uniapp封装toast消息提示组件(js)

说明:本组件借用到uv-ui前端框架的<uv-toast ref="toast"></uv-toast>作为消息提示,有条件的可以自己设计。另外主要用到@uni-ku/root@1.1.0。 目录结构(主要文件): 安装@uni-ku/root@1.1.0 npm install -D @uni-ku/rootvite.config.js: import {d…

8.5 Whisper:解锁语音识别新高度的智能助手

Whisper:解锁语音识别新高度的智能助手 引言:从语音到文字的技术飞跃 在当今的人工智能技术中,语音识别 已成为人机交互的重要环节。从语音助手到实时字幕生成,语音识别技术正在改变我们的沟通方式。OpenAI Whisper 是一款功能强大的开源语音识别模型,它结合了高精度、语…