数据结构与算法之排序算法-(计数,桶,基数排序)
排序算法是数据结构与算法中最基本的算法之一,其作用就是将一些可以比较大小的数据进行有规律的排序,而想要实现这种排序就拥有很多种方法~
📚 非线性时间比较类:
那么我将通过几篇文章,将排序算法中各种算法细化的,详尽的为大家呈现出来:
📕 插入类排序:数据结构与算法之排序算法-插入排序-CSDN博客
📖 直接插入排序
📖 希尔排序
📕 交换类排序:数据结构与算法之排序算法-快速排序(分治)-CSDN博客
📖 冒泡排序
📖 冒泡排序-优化
📖 快速排序(Hoare,挖坑法,前后指针法)
📖 快速排序-优化
📕 选择类排序:数据结构与算法之排序算法-选择排序-CSDN博客
📖 简单选择排序
📖 堆排序
📕 归并类排序:数据结构与算法之排序算法-归并排序-CSDN博客
📖 归并排序
📚 线性时间非比较类:
📕 非比较类排序:[本篇]
📖 计数排序
📖 桶排序
📖 基数排序
一、计数排序
稳定性:稳定
时间复杂度:O(n + m)
额外空间复杂度:O(n + m)
大家应该也注意到了,这次学习到的排序算法,不仅具有稳定性,时间复杂度竟然还趋近O(n)!这是相当快的一种排序算法了。
那么为什么它能达到这么优秀的时间复杂度呢?主要就是因为它并不需要对元素之间进行比较~那么有人可能就要发出疑问,不进行比较又如何知道元素与元素间的大小关系呢?
① 计数排序
📚 算法思想:
计数排序的基本思想:把原数组元素作为数组的下标,创建一个临时数组 arr,使得 arr 至少能将原数组中所有数据都存入数组中。
然后遍历原数组,将遍历到的元素与 arr 下标进行匹配,并使 arr[index]++,代表该数字出现的次数 +1,而将数组遍历结束后,arr 从 start 下标到 end 下标存储的数据正好由下标默认排序好了,并且数据也准确的存到了正确位置~
了解了计数排序的基本思想后,大家或许也知道了为什么它的速度如此之快,相应的,大家应该也能理解为什么它没有"快速排序","归并排序"那么实用了,那就是"额外空间复杂度太高"
⭐ 图示:

📖 代码示例:
public static void countingSort(int[] array) {int max = array[0];for (int i = 1; i < array.length; i++) {if (array[i] > max) {max = array[i];}}int[] arr = new int[max + 1];for (int i = 0; i < array.length; i++) {int index = array[i];arr[index]++;}int k = 0;for (int i = 0; i < arr.length; i++) {while (arr[i] != 0) {array[k] = i;arr[i]--;k++;}}}
② 计数排序(优化)
上述代码中,我们简单实现了计数排序,但是这样是有缺点的:
📕 当数组中元素过大:如 [5000,5005,5010],如果创建一个大小为 5011 的数组,那么浪费的空间就会特别大。
📕 当数组中存在负数:如 [1,2,3,-1],创建数组后,是搜索不到 ' -1 ' 下标的。
📚 算法思想:
在原来的基础上,同时算出数组中的最小值,创建一个大小为[max - min + 1]的数组,这样就能有效的降低额外空间的损耗。
并且放入和取出元素时,寻找的下标也相应变成 arr[index] - min ,这样就能够彻底避免访问下标小于0的非法访问。
📖 代码示例:
public static void countingSort(int[] array) {int max = array[0];int min = array[0];for (int i = 1; i < array.length; i++) {if (array[i] > max) {max = array[i];}if (array[i] < min) {min = array[i];}}int[] arr = new int[max - min + 1];for (int i = 0; i < array.length; i++) {int index = array[i] - min;arr[index]++;}int k = 0;for (int i = 0; i < arr.length; i++) {while (arr[i] != 0) {array[k] = i + min;arr[i]--;k++;}}}
③ 效率测试

顺便一提,快速排序达到的速度为40ms左右,归并排序达到的速度为30ms左右~
二、桶排序
稳定性:稳定
时间复杂度:O(n)
额外空间复杂度:O(m)
上面的计数排数,很快倒是很快,但是它也有相应的缺点
📕 无法对浮点型数据进行排序,因为无法通过浮点型数据查找对应下标

这个算法属于计数排序的一种升级版,它的思想和计数排序类似,也是通过数据的值进行分类。
但它和计数排序也有些不同:
📕 它并没有通过数据的值来直接对应下标,而是通过创建一些"桶",并且为它们设定"区间",从而通过数据查找对应区间,这样就能够避免"浮点数非法查找下标"的问题了。
① 桶排序
📚 算法思想:
桶排序的基本思想:根据原数组的最大值 max 和最小值 min 来划分区间,由这些区间来创造一些"桶"。而每一个桶代表一个区间范围,里面可以承载一个或多个元素。
创建好"桶"后,遍历原数组,将数组中的数据放到对应区间的桶中,然后再分别将桶中的元素排序,这样排好序后,就能够得到我们最终想要的有序数组了。
⭐ 图示:

📖 代码示例:
public static double[] bucketSort(double[] array) {//取最大值和最小值,并求出差值int len = array.length;double max = array[0];double min = array[0];for (int i = 1; i < len; i++) {max = Math.max(array[i], max);min = Math.min(array[i], min);}double d = max - min;//创建桶int bucketNum = len;ArrayList<LinkedList<Double>> bucketList = new ArrayList<LinkedList<Double>>(bucketNum);for(int i = 0;i < bucketNum;i++){bucketList.add(new LinkedList<Double>());}//将数组元素放入桶中for(int i = 0;i < len;i++){int num = (int)((array[i] - min) * (bucketNum - 1) / d);bucketList.get(num).add(array[i]);}//对每个桶进行排序for(int i = 0;i < bucketList.size();i++){Collections.sort(bucketList.get(i));}double[] sortArr = new double[len];int index = 0;for(LinkedList<Double> list:bucketList){for(double element: list){sortArr[index++] = element;}}return sortArr;}

三、基数排序
稳定性:稳定
时间复杂度:O(n * k)
额外空间复杂度:O(n * k)
① 基数排序
📚 算法思想:
基数排序的基本思想:基数排序的算法思想是,将整数按照位数分别切割成不同的数字。
当每次将数组中的数据按位数分割结束后,分别放入以位数为单位的"桶"中。
然后遍历桶,按照顺序将元素取出,再重新进行分割,入桶等操作,直到分割位数的次数达到了数组中位数最高的元素的限制,排序结束。
📖 代码示例:
public static int[] radioSort(int[] arr) {if(arr == null || arr.length < 2) return arr;int n = arr.length;int max = arr[0];// 找出最大值,计算最大值是几位数for (int i = 1; i < n; i++) {if(max < arr[i]) max = arr[i];}int num = 1;while (max / 10 > 0) {num++;max = max / 10;}// 创建10个桶ArrayList<LinkedList<Integer>> bucketList = new ArrayList<>(10);for (int i = 0; i < 10; i++) {bucketList.add(new LinkedList<Integer>());}// 进行排序for (int i = 1; i <= num; i++) {for (int j = 0; j < n; j++) {int radio = (arr[j] / (int)Math.pow(10,i-1)) % 10;bucketList.get(radio).add(arr[j]);}int k = 0;for (int j = 0; j < 10; j++) {for (Integer t : bucketList.get(j)) {arr[k++] = t;}}}return arr;}
那么这篇关于计数排序,桶排序,基数排序的文章到这里就结束啦,作者能力有限,如果有哪里说的不够清楚或者不够准确,还请各位在评论区多多指出,我也会虚心学习的,我们下次再见啦
相关文章:
数据结构与算法之排序算法-(计数,桶,基数排序)
排序算法是数据结构与算法中最基本的算法之一,其作用就是将一些可以比较大小的数据进行有规律的排序,而想要实现这种排序就拥有很多种方法~ 📚 非线性时间比较类: 那么我将通过几篇文章,将排序算法中各种算法细化的&a…...
Word正文中每两个字符之间插入一个英文半角空格
Word正文中每两个字符之间插入一个英文半角空格 修改前 修改后 替换方法 快捷键 Ctrl H 唤出查找和替换界面依次输入上述内容全部替换即可 参考链接 【【2025年3月】计算机二级MS Office 2016 真题讲解视频打卡】 【精准空降到 25:27】...
把 DeepSeek1.5b 部署在显卡小于4G的电脑上
这里写自定义目录标题 介绍准备安装 Ollama查看CUDA需要版本安装CudaToolkit检查Cuda是否装好设置Ollama环境变量验证是否跑在GPU上ollama如何导入本地下载的模型安装及配置docker安装open-webui启动open-webui开始对话 调整gpu精度 介绍 Deepseek1.5b能够运行在只用cpu和gpu内…...
A4988一款带转换器和过流保护的 DMOS 微步驱动器的使用方式
A4988是一款带转换器和过流保护的 DMOS 微步驱动器,用于驱动双极步进电动机。它支持全、半、1/4、1/8 及 1/16 步进模式,输出驱动性能可达 35 V 及 2 A。其特点包括简单的步进和方向控制接口、可调电位器调节最大电流输出、自动电流衰减模式检测/选择以及…...
一口井深7米,一只蜗牛从井底往上爬每天爬3米掉下去1米,问几天能爬上井口?
一个井深7米,一只蜗牛从井底往上爬每天爬3米掉下去1米,问几天能爬上井口? 1. 通用解法 构建一个通用的解法,适用于任何井深和蜗牛的爬升、下滑距离。 问题描述: 井深为 H H H 米。蜗牛每天向上爬升 U U U 米。每…...
Asp.Net Core MVC 中级开发教程
Asp.Net Core MVC 中级开发教程 一、Asp.Net Core Mvc 区域使用 ASP.NET Core MVC的Areas使用整理 - 天马3798 - 博客园 二、Asp.Net Core 路径处理 Asp.Net Core Web相对路径、绝对路径整理 Asp.Net Core获取当前上下文对象 三、Asp.Net Core 服务使用和封装 四、Asp.Net …...
Windows上安装Go并配置环境变量(图文步骤)
前言 1. 本文主要讲解的是在windows上安装Go语言的环境和配置环境变量; Go语言版本:1.23.2 Windows版本:win11(win10通用) 下载Go环境 下载go环境:Go下载官网链接(https://golang.google.cn/dl/) 等待…...
C++效率掌握之STL库:string底层剖析
文章目录 1.学习string底层的必要性2.string类对象基本函数实现3.string类对象的遍历4.string类对象的扩容追加5.string类对象的插入、删除6.string类对象的查找、提取、大小调整7.string类对象的流输出、流提取希望读者们多多三连支持小编会继续更新你们的鼓励就是我前进的动力…...
【Erdas实验教程】004:影像镶嵌拼接
文章目录 一、实验目标二、实验数据三、实验过程一、实验目标 掌握具有坐标系且有重叠的多个影像的镶嵌。 二、实验数据 本实验数据为2景landsat TM影像和1景mss影像,如下所示: 数据获取方式:订阅专栏后,从私信查收。 三、实验过程 (1)启动镶嵌工具 在erdas中,常用…...
SpringMVC 请求参数接收
目录 请求 传递单个参数 基本类型参数传递 未传递参数 ?传递参数类型不匹配 传递多个参数 传递对象 后端参数重命名 传递数组 传递集合 传递JSON数据 JSON是什么 JSON的优点 传递JSON对象 获取URL中的参数 文件上传 在浏览器与程序进行交互时,主要…...
[高等数学]换元积分法
一、知识点 (一) 第一类换元法 定理1 设 f ( u ) f(u) f(u) 具有原函数, u φ ( x ) u\varphi(x) uφ(x) 可导,则有换元公式: ∫ f [ φ ( x ) ] φ ′ ( x ) d x [ ∫ f ( u ) d u ] u φ ( x ) . \int f[\varphi(x)]\varphi (x)dx[\int f(u)du]…...
Redis简介、常用命令及优化
文章目录 一、关系数据库??与非关系型数据库概述 1. 关系型数据库2. 非关系型数据库3.关系数据库与非关系型数据库区别 二、Redis简介 1.Redis的单线程模式2.Redis 优点3.Redis 缺点 三、安装redis四、Redis 命令工具五、Redis 数据库常用命令六、Redis 多数据库常用命令七、…...
大模型训练为什么依赖GPU
近年来,随着人工智能技术的飞速发展,特别是深度学习领域的进步,大模型的训练逐渐成为研究和工业界的热点。作为大模型训练中的核心硬件,GPU(图形处理单元)扮演了至关重要的角色。那么,为什么大模…...
帕金森病与三叉神经痛的基因关联分析
帕金森病(Parkinsons Disease, PD)和三叉神经痛(Trigeminal Neuralgia, TN)是两种不同的神经系统疾病,前者主要影响运动功能,而后者则表现为剧烈的面部疼痛。尽管这两种疾病在临床表现上有显著差异…...
【Android开发】华为手机安装包安装失败“应用是非正式版发布版本,当前设备不支持安装”问题解决
问题描述 我们将Debug版本的安装包发送到手机上安装,会发现华为手机有如下情况 解决办法 在文件gradle.properties中粘贴代码: android.injected.testOnlyfalse 最后点击“Sync now”,等待重新加载gradle资源即可 后面我们重新编译Debug安装…...
栈与队列(C语言版)
文章目录 栈与队列1. 栈基本操作实现(基于链表)代码运行结果 应用场景 2. 队列基本操作实现代码运行结果 应用场景 栈与队列 1. 栈 栈是一种操作受限的线性结构。操作受限体现在,栈只能在一端添加和删除元素,符合后进先出 ( LIFO ) 的特性,…...
stl里的deque 中控map 假如用完了,该如何处理
在 C 的标准模板库(STL)中,std::deque(双端队列)使用一种分段连续的存储结构,通过一个中控器(通常称为中控 map)来管理多个固定大小的存储块(缓冲区)。当这个…...
Git GUI设置中文的方法及使用
链接: Git Bash和Git GUI设置中文的方法 链接: Git 基本操作...
代码书写常用快捷建
唤出剪切板 Windows 系统 :Win V Mac 系统: 在 Mac 电脑上,可以点击桌面菜单栏中的 “编辑”,在下拉菜单中选择 “显示剪贴板” 来打开剪贴板。 跳转和撤回跳转 在vscode软件中可以通过ctrl+鼠标左键可以进行跳转…...
MySQL 索引失效处理:原因分析与优化实战
MySQL 索引失效处理:原因分析与优化实战 MySQL 索引失效处理:原因分析与优化实战引言一、什么是索引失效?二、索引失效的常见原因2.1 查询条件中使用函数或表达式示例:原因: 2.2 数据类型不匹配示例:原因&a…...
SciencePlots——绘制论文中的图片
文章目录 安装一、风格二、1 资源 安装 # 安装最新版 pip install githttps://github.com/garrettj403/SciencePlots.git# 安装稳定版 pip install SciencePlots一、风格 简单好用的深度学习论文绘图专用工具包–Science Plot 二、 1 资源 论文绘图神器来了:一行…...
使用van-uploader 的UI组件,结合vue2如何实现图片上传组件的封装
以下是基于 vant-ui(适配 Vue2 版本 )实现截图中照片上传预览、删除功能,并封装成可复用组件的完整代码,包含样式和逻辑实现,可直接在 Vue2 项目中使用: 1. 封装的图片上传组件 ImageUploader.vue <te…...
DIY|Mac 搭建 ESP-IDF 开发环境及编译小智 AI
前一阵子在百度 AI 开发者大会上,看到基于小智 AI DIY 玩具的演示,感觉有点意思,想着自己也来试试。 如果只是想烧录现成的固件,乐鑫官方除了提供了 Windows 版本的 Flash 下载工具 之外,还提供了基于网页版的 ESP LA…...
.Net Framework 4/C# 关键字(非常用,持续更新...)
一、is 关键字 is 关键字用于检查对象是否于给定类型兼容,如果兼容将返回 true,如果不兼容则返回 false,在进行类型转换前,可以先使用 is 关键字判断对象是否与指定类型兼容,如果兼容才进行转换,这样的转换是安全的。 例如有:首先创建一个字符串对象,然后将字符串对象隐…...
在Ubuntu24上采用Wine打开SourceInsight
1. 安装wine sudo apt install wine 2. 安装32位库支持,SourceInsight是32位程序 sudo dpkg --add-architecture i386 sudo apt update sudo apt install wine32:i386 3. 验证安装 wine --version 4. 安装必要的字体和库(解决显示问题) sudo apt install fonts-wqy…...
回溯算法学习
一、电话号码的字母组合 import java.util.ArrayList; import java.util.List;import javax.management.loading.PrivateClassLoader;public class letterCombinations {private static final String[] KEYPAD {"", //0"", //1"abc", //2"…...
Mysql中select查询语句的执行过程
目录 1、介绍 1.1、组件介绍 1.2、Sql执行顺序 2、执行流程 2.1. 连接与认证 2.2. 查询缓存 2.3. 语法解析(Parser) 2.4、执行sql 1. 预处理(Preprocessor) 2. 查询优化器(Optimizer) 3. 执行器…...
CRMEB 中 PHP 短信扩展开发:涵盖一号通、阿里云、腾讯云、创蓝
目前已有一号通短信、阿里云短信、腾讯云短信扩展 扩展入口文件 文件目录 crmeb\services\sms\Sms.php 默认驱动类型为:一号通 namespace crmeb\services\sms;use crmeb\basic\BaseManager; use crmeb\services\AccessTokenServeService; use crmeb\services\sms\…...
Golang——9、反射和文件操作
反射和文件操作 1、反射1.1、reflect.TypeOf()获取任意值的类型对象1.2、reflect.ValueOf()1.3、结构体反射 2、文件操作2.1、os.Open()打开文件2.2、方式一:使用Read()读取文件2.3、方式二:bufio读取文件2.4、方式三:os.ReadFile读取2.5、写…...
基于江科大stm32屏幕驱动,实现OLED多级菜单(动画效果),结构体链表实现(独创源码)
引言 在嵌入式系统中,用户界面的设计往往直接影响到用户体验。本文将以STM32微控制器和OLED显示屏为例,介绍如何实现一个多级菜单系统。该系统支持用户通过按键导航菜单,执行相应操作,并提供平滑的滚动动画效果。 本文设计了一个…...
