当前位置: 首页 > article >正文

数据结构与算法之排序算法-(计数,桶,基数排序)

排序算法是数据结构与算法中最基本的算法之一,其作用就是将一些可以比较大小的数据进行有规律的排序,而想要实现这种排序就拥有很多种方法~

📚 非线性时间比较类

那么我将通过几篇文章,将排序算法中各种算法细化的,详尽的为大家呈现出来:

📕 插入类排序:数据结构与算法之排序算法-插入排序-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;}

那么这篇关于计数排序,桶排序,基数排序的文章到这里就结束啦,作者能力有限,如果有哪里说的不够清楚或者不够准确,还请各位在评论区多多指出,我也会虚心学习的,我们下次再见啦

相关文章:

数据结构与算法之排序算法-(计数,桶,基数排序)

排序算法是数据结构与算法中最基本的算法之一&#xff0c;其作用就是将一些可以比较大小的数据进行有规律的排序&#xff0c;而想要实现这种排序就拥有很多种方法~ &#x1f4da; 非线性时间比较类&#xff1a; 那么我将通过几篇文章&#xff0c;将排序算法中各种算法细化的&a…...

【ISO 14229-1:2023 UDS诊断(会话控制0x10服务)测试用例CAPL代码全解析②】

ISO 14229-1:2023 UDS诊断【会话控制0x10服务】_TestCase02 作者&#xff1a;车端域控测试工程师 更新日期&#xff1a;2025年02月15日 关键词&#xff1a;UDS诊断、0x10服务、诊断会话控制、ECU测试、ISO 14229-1:2023 TC10-002测试用例 用例ID测试场景验证要点参考条款预期…...

MATLAB图像处理:图像特征概念及提取方法HOG、SIFT

图像特征是计算机视觉中用于描述图像内容的关键信息&#xff0c;其提取质量直接影响后续的目标检测、分类和匹配等任务性能。本文将系统解析 全局与局部特征的核心概念&#xff0c;深入讲解 HOG&#xff08;方向梯度直方图&#xff09;与SIFT&#xff08;尺度不变特征变换&…...

kibana es 语法记录 elaticsearch

目录 一、认识elaticsearch 1、什么是正向索引 2、什么是倒排索引 二、概念 1、说明 2、mysql和es的对比 三、mapping属性 1、定义 四、CRUD 1、查看es中有哪些索引库 2、创建索引库 3、修改索引库 4、删除索引库 5、新增文档 6、删除文档 5、条件查询 一、认识…...

手写一个Java Android Binder服务及源码分析

手写一个Java Android Binder服务及源码分析 前言一、Java语言编写自己的Binder服务Demo1. binder服务demo功能介绍2. binder服务demo代码结构图3. binder服务demo代码实现3.1 IHelloService.aidl3.2 IHelloService.java&#xff08;自动生成&#xff09;3.3 HelloService.java…...

MAC 系统关闭屏幕/睡眠 后被唤醒 Wake Requests

问题&#xff1b;查看wake 日志 pmset -g log | grep "Wake Requests" 为 Wake Requests [*processdasd requestSleepService...info"com.apple.alarm.user-invisible-com.apple.calaccessd...电源设置命令参考&#xff1a; pmset -g sched //查看定时…...

【Elasticsearch】运行时字段(Runtime Fields)索引时定义运行时字段

在 Elasticsearch 中&#xff0c;运行时字段&#xff08;Runtime Fields&#xff09;是一种在查询时动态计算的字段&#xff0c;而不是在索引时预先存储的字段。运行时字段为数据处理提供了极大的灵活性&#xff0c;尤其是在处理结构不固定的日志数据或需要动态生成字段值的场景…...

elasticsearch8 linux版以服务的方式启动

1.创建系统服务文件 对于使用 systemd 作为系统初始化系统的 Linux 发行版&#xff08;如 CentOS 7 及以上、Ubuntu 16.04 及以上&#xff09;&#xff0c;需要创建一个 systemd 服务文件。以 root 用户或具有 sudo 权限的用户身份执行以下操作&#xff1a; sudo vim /etc/sy…...

【动态规划篇】:当回文串遇上动态规划--如何用二维DP“折叠”字符串?

✨感谢您阅读本篇文章&#xff0c;文章内容是个人学习笔记的整理&#xff0c;如果哪里有误的话还请您指正噢✨ ✨ 个人主页&#xff1a;余辉zmh–CSDN博客 ✨ 文章所属专栏&#xff1a;动态规划篇–CSDN博客 文章目录 一.回文串类DP核心思想&#xff08;判断所有子串是否是回文…...

Windows 安装 GDAL 并配置 Rust-GDAL 开发环境-1

Rust-GDAL 是 Rust 语言的 GDAL&#xff08;Geospatial Data Abstraction Library&#xff09; 绑定库&#xff0c;用于处理地理数据。由于 GDAL 依赖较多&#xff0c;在 Windows 上的安装相对复杂&#xff0c;本文档将介绍如何安装 GDAL 并配置 Rust-GDAL 的开发环境。 1. 检…...

第1期 定时器实现非阻塞式程序 按键控制LED闪烁模式

第1期 定时器实现非阻塞式程序 按键控制LED闪烁模式 解决按键扫描&#xff0c;松手检测时阻塞的问题实现LED闪烁的非阻塞总结补充&#xff08;为什么不会阻塞&#xff09; 参考江协科技 KEY1和KEY2两者独立控制互不影响 阻塞&#xff1a;如果按下按键不松手&#xff0c;程序就…...

开源语音克隆项目 OpenVoice V2 本地部署

#本机环境 WIN11 I5 GPU 4060ti 16G 内存 32G #开始 git clone https://github.com/myshell-ai/OpenVoice.git conda create -n opvenv python3.9 -y conda activate opvenv pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/…...

DeepSeek大模型一键部署解决方案:全平台多机分布式推理与国产硬件优化异构计算私有部署

DeepSeek R1 走红后&#xff0c;私有部署需求也随之增长&#xff0c;各种私有部署教程层出不穷。大部分教程只是简单地使用 Ollama、LM Studio 单机运行量化蒸馏模型&#xff0c;无法满足复杂场景需求。一些操作配置也过于繁琐&#xff0c;有的需要手动下载并合并分片模型文件&…...

如何利用PLM软件有效地推进制造企业标准化工作?

在智能制造浪潮的推动下&#xff0c;中国制造业正面临从“规模扩张”向“质量提升”的关键转型。工信部数据显示&#xff0c;85%的制造企业在产品研发、生产过程中因标准化程度不足导致效率损失超20%&#xff0c;而标准化水平每提升10%&#xff0c;企业综合成本可降低5%-8%。如…...

CloudberryDB(六)SPI拓展功能

SPI&#xff08;Server Programming Interface&#xff09;在实现原理主要涉及以下几个方面&#xff1a; 1. **模块化设计**&#xff1a;SPI模块是内核中的一个独立模块&#xff0c;允许内核开发者在C函数中执行SQL语句&#xff0c;并管理事务。这种设计使得开发者可以在不修改…...

非谓语动词三驾马车

文章目录 1. 不定式基本结构不定式的由来1.不受主语的人称和数的限制2.没有限定时态3.可以在句子中充当不同的成分 常见句子成分1. 作主语2. 作表语3. 作宾语4. 作定语5. 作状语 不定式 vs 动名词 2. 动名词动名词做成分作主语作主语补语作定语作宾语介词宾语 3. 分词(现在、过…...

环境影响评价(EIA)中,土地利用、植被类型及生态系统图件的制作

在环境影响评价&#xff08;EIA&#xff09;中&#xff0c;土地利用、植被类型及生态系统图件的制作需依据科学、法规和技术规范&#xff0c;以确保数据的准确性和图件的规范性。以下是主要的制作依据&#xff1a; 1. 法律法规与政策依据 《中华人民共和国环境影响评价法》 明确…...

Lineageos 22.1(Android 15)更换开机动画

一、原理简介 我们直接用最简单的替换zip的方式来更换开机动画&#xff0c;首先我们要查看系统代码使用的zip包的路径&#xff0c;可能与aosp原生的代码不一定一样。 /frameworks/base/cmds/bootanimation/BootAnimation.cpp bool BootAnimation::threadLoop() {ATRACE_CALL(…...

大语言模型推理中的显存优化 有哪些

大语言模型推理中的显存优化 有哪些 目录 大语言模型推理中的显存优化 有哪些显存优化背景Offloading/Checkpoint原理举例显存优化背景 在大语言模型推理时,显存是显著瓶颈。以开源的BLOOM 176B模型为例,在8张A100计算卡上,通常对话设置下仅能进行批量为10左右的推理。为缓…...

更高效实用 vscode 的常用设置

VSCode 可以说是文本编辑神器, 不止程序员使用, 普通人用其作为文本编辑工具, 更是效率翻倍. 这里分享博主对于 VSCode 的好用设置, 让 VSCode 如虎添翼 进入设置 首先进入设置界面, 后续都在这里进行配置修改 具体设置 每项配置通过搜索关键字, 来快速定位配置项 自动保存…...

【异或数列——博弈论】

题目 思路 异或和为0&#xff08;即每一位都有偶数个1&#xff09;&#xff1a;平局最高有效位只有唯一的1&#xff1a;先手必胜最高有效位有奇数个1&#xff0c;偶数个0&#xff1a;先手必胜 若先选1产生优势&#xff0c;则剩下偶数个1&#xff0c;偶数个0&#xff1a;对手选…...

阿里云大文件ossutil工具进行上传下载,该工具支持断点续传

ossutil工具进行上传下载&#xff0c;该工具支持断点续传、文件分片、多文件同时上传等 下载和配置 https://help.aliyun.com/zh/oss/developer-reference/install-ossutil 上传操作 https://help.aliyun.com/zh/oss/developer-reference/upload-objects-6 下载操作 https://h…...

草图绘制技巧

1、点击菜单栏文件–》新建–》左下角高级新手切换–》零件&#xff1b; 2、槽口&#xff1a;直槽口&#xff0c;中心点槽口&#xff0c;三点源槽口&#xff0c;中心点圆弧槽口&#xff1b; 3、草图的约束&#xff1a;需要按住ctrl键&#xff0c;选中两个草图&#xff0c;然后…...

Spring Boot中如何自定义Starter

文章目录 Spring Boot中如何自定义Starter概念和作用1. 概念介绍2. 作用和优势2.1 简化依赖管理2.2 提供开箱即用的自动配置2.3 标准化和模块化开发2.4 提高开发效率2.5 提供灵活的配置覆盖3. 应用场景创建核心依赖1. 确定核心依赖的作用2. 创建 starter-core 模块2.1 依赖管理…...

内容中台构建高效数字化内容管理新范式

内容概要 在数字化转型浪潮中&#xff0c;高效的内容管理能力已成为企业构建核心竞争力的关键要素。通过动态发布引擎、元数据智能分类与跨平台协作机制&#xff0c;企业能够实现内容的实时触达与精准分发&#xff0c;同时确保知识资产在多终端环境下的无缝适配与安全共享。这…...

QGIS热力图制作全流程详解

一、热力图的概念与应用 热力图&#xff08;Heatmap&#xff09;是一种通过颜色梯度展示空间数据密度的可视化工具&#xff0c;常用于分析点数据的聚集程度。例如&#xff0c;犯罪热点、人口分布、交通流量等场景均可通过热力图直观呈现。QGIS作为开源GIS软件&#xff0c;支持…...

切换镜像源(npm)

常见的npm镜像源 官方源 URL: https://registry.npmjs.org 淘宝镜像源&#xff08;npmmirror&#xff09; URL: https://registry.npmmirror.com 其他常用镜像源 URL: https://registry.cnpmjs.org (CNPM) 这里是引用 切换npm镜像源 切换到官方源 npm config set registry http…...

PyQt组态软件 拖拽设计界面测试

PyQt组态软件测试 最近在研究PyQt,尝试写个拖拽设计界面的组态软件&#xff0c;目前实现的功能如下&#xff1a; 支持拖入控件&#xff0c;鼠标拖动控件位置 拖动控件边缘修改控件大小支持属性编辑器&#xff0c;修改当前选中控件的属性 拖动框选控件&#xff0c;点选控件 控…...

深度学习R4周:LSTM-火灾温度预测

&#x1f368; 本文为&#x1f517;365天深度学习训练营中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 任务&#xff1a; 数据集中提供了火灾温度&#xff08;Tem1&#xff09;、一氧化碳浓度&#xff08;CO 1&#xff09;烟雾浓度&#xff08;Soot 1&#xff09;…...

Datawhale 数学建模导论二 笔记1

第6章 数据处理与拟合模型 本章主要涉及到的知识点有&#xff1a; 数据与大数据Python数据预处理常见的统计分析模型随机过程与随机模拟数据可视化 本章内容涉及到基础的概率论与数理统计理论&#xff0c;如果对这部分内容不熟悉&#xff0c;可以参考相关概率论与数理统计的…...