【算法】计数排序、桶排序、基数排序



算法系列八:非比较排序
一、计数排序
1.实现
1.1步骤
1.2代码
2.性质
2.1稳定性
2.1.1从前往后前始版:
2.1.2从后往前末始版:
2.2复杂度
2.2.1时间复杂度
2.2.2空间复杂度
二、桶排序
1.实现
1.1步骤
1.2代码
2.稳定性
三、基数排序
1.原理
2.代码
鸽巢原理
鸽子归巢,待排序数据归到有序组群中按大小归进有序组群来排,数越大,归到的有序组就在越后的,数越小,归到的有序组就在越前的
- 如果有序组以一个元素一个元素划分的,实现的是元素组归巢排序,即计数排序
- 如果有序组按范围多个元素为一组划分的,实现的是范围组归巢排序,即桶排序
一、计数排序
1.实现
1.1步骤
- 开辟数据范围内的所有元素都有各自对应的元素组巢穴,范围内一共有多少种个数据,就开辟每种个数据都有对应的多大的数组,比如90(max) - 10(min) = 80(种个数据)
- 归巢时,通过该数据-数据范围内的最小值得到所归巢的下标,然后在数组元素巢中计数表示归巢
- 因为巢内只有一种个数据直接就是有序的,所以所有数据归完巢在巢层面有序时所有数据就已经有序了,最后将它们按顺序地赶出巢加回去即得原来有序的数据

1.2代码
public static void countSort(int[] array) {//1.求当前数据的最大值和最小值int minVal = array[0];int maxVal = array[0];for (int i = 1; i < array.length; i++) {if(array[i] < minVal) {minVal = array[i];}if(array[i] > maxVal) {maxVal = array[i];}}//2.根据数据最大值和最小值来确定元素组巢穴数组的大小int[] count = new int[maxVal-minVal+1];//3.遍历原来的数据进行归巢排序for (int i = 0; i < array.length; i++) {count[array[i]-minVal]++;}//4.将元素组巢穴里已排好序的数据按顺序写回arrayint index = 0;//重新表示array数组的下标for (int i = 0; i < count.length; i++) {while (count[i] > 0) {array[index] = i+minVal;index++;count[i]--;}}}
}
2.性质
2.1稳定性
将每个数据都归到巢中完成有序时,根据巢中有序来的元素的计数个数,可以将巢改装成装每种个元素有序排的始位置,通过对应顺序遍历原数组将数据正确稳定地放在排好序的各自位置上,能实现稳定的排序,所以计数排序是稳定的排序
2.1.1从前往后前始版:
原本巢中装的是鸽子的计数数量,现在巢里面改装成装种个鸽子从前往后的起始位置来进行排序:

2.1.2从后往前末始版:
巢里面改装成装种个鸽子从后往前的起始位置来进行排序:

2.2复杂度
2.2.1时间复杂度
找最大最小值确定范围种个数据遍历原数组用了n,原数组数据每个去归巢用了n,范围x种个元素巢每个去赶,所以时间复杂度为2n + x,即O(n+x)
2.2.2空间复杂度
范围x种个数据需要开辟x个元素巢的数组,所以空间复杂度为O(x)
二、桶排序
1.实现
1.1步骤
- 开辟数据范围内所有元素都有对应的范围数组组巢穴,将所有数据入范围组巢穴先进行第一轮巢穴外的排好序,此时巢外已经有序了
- 再进行第二轮各自巢穴内的排好序,此时就巢外、巢内都有序所有数据都有序了
- 最后按顺序地将它们从数组巢中赶出即得有序的数据

1.2代码
public static int[] bucketSort(int[] arr) {// 边界条件:空数组或单个元素直接返回if (arr.length <= 1) {return arr.clone();}// Step 1: 确定数据范围int minVal = Integer.MAX_VALUE;int maxVal = Integer.MIN_VALUE;for (int num : arr) {if (num < minVal) minVal = num;if (num > maxVal) maxVal = num;}// 处理所有元素相同的情况if (maxVal == minVal) {return arr.clone();}// Step 2: 初始化桶int bucketCount = (int) Math.sqrt(arr.length) + 1; // 桶数量=数组长度的平方根(经验值)double bucketRange = (double)(maxVal - minVal) / bucketCount;List<List<Integer>> buckets = new ArrayList<>(bucketCount);for (int i = 0; i < bucketCount; i++) {buckets.add(new ArrayList<>());}// Step 3: 元素分配到桶中for (int num : arr) {// 计算元素应该属于哪个桶int index = (int)((num - minVal) / bucketRange);// 处理最大值刚好落在最后一个桶外的情况if (index == bucketCount) index--;buckets.get(index).add(num);}// Step 4: 对每个桶内部排序for (List<Integer> bucket : buckets) {Collections.sort(bucket); // 使用内置排序算法,决定了桶排序的稳定性}// Step 5: 合并桶int[] sortedArr = new int[arr.length];int idx = 0;for (List<Integer> bucket : buckets) {for (int num : bucket) {sortedArr[idx++] = num;}}return sortedArr;}
2.稳定性
稳定性取决于在第二轮巢内开始排相同大小的元素时所用的排序方法是否具有稳定性
三、基数排序
1.原理
- 先进行个位排序,能实现个位一位数有序
- 个位有序下,再进行十位优先排序,能实现十位个位两位数有序
- 十个位有序下,再进行百位优先排序,能实现百位十位个位三位数有序

2.代码
public static int[] radixSort(int[] arr) {if (arr.length <= 1) {return arr.clone();}// Step 1: 确定最大数的位数int maxNum = Integer.MIN_VALUE;for (int num : arr) {if (num > maxNum) maxNum = num;}// Step 2: 按每位进行计数排序(从低位到高位)int exp = 1; // 从个位开始while (maxNum / exp > 0) {// 初始化10个数字桶(0-9)List<List<Integer>> buckets = new ArrayList<>(10);for (int i = 0; i < 10; i++) {buckets.add(new ArrayList<>());}// 按当前位分配到桶中for (int num : arr) {int digit = (num / exp) % 10; // 提取当前位的数字buckets.get(digit).add(num);}// 重组数组int idx = 0;for (List<Integer> bucket : buckets) {for (int num : bucket) {arr[idx++] = num;}}exp *= 10; // 处理更高位}return arr;}相关文章:
【算法】计数排序、桶排序、基数排序
算法系列八:非比较排序 一、计数排序 1.实现 1.1步骤 1.2代码 2.性质 2.1稳定性 2.1.1从前往后前始版: 2.1.2从后往前末始版: 2.2复杂度 2.2.1时间复杂度 2.2.2空间复杂度 二、桶排序 1.实现 1.1步骤 1.2代码 2.稳定性 三、…...
Halcon应用:相机标定
提示:若没有查找的算子,可以评论区留言,会尽快更新 Halcon应用:相机标定 前言一、Halcon应用?二、应用实战1、图像理解1.1、开始标定 前言 本篇博文主要用于记录学习Halcon中算子的应用场景,及其使用代码和…...
【C++ 程序设计】实战:C++ 实践练习题(31~40)
目录 31. 数列:s 1 + 2 + 3 + … + n 32. 数列:s 1 - 2 - 3 - … - n 33. 数列:s 1 + 2 - 3 + … - n 34. 数列:s 1 - 2 + 3 - … &#…...
【perf】perf工具的使用生成火焰图
文章目录 1. What is perf?2. perf使用2.1 perf的子工具集2.2 常用指令perf list指令格式参数perf中事件分类使用示例 perf stat指令格式参数 perf top指令格式参数交互式界面操作使用示例 perf record指令格式参数使用示例 perf report指令格式参数交互式界面操作使用示例 pe…...
绿幕抠图直播软件-蓝松抠图插件--使用相机直播,灯光需要怎么打?
使用SONY相机进行绿幕抠图直播时,灯光布置是关键,直接影响抠图效果和直播画质。以下是详细的灯光方案和注意事项: 一、绿幕灯光布置核心原则 均匀照明:绿幕表面光线需均匀,避免阴影和反光(亮度差控制在0.5…...
从外网访问局域网服务器的方法
一、为什么局域网的服务器无法在外网访问? 服务器、电脑之间靠IP地址寻址,目前大部分基于IPV4进行寻址访问。但是因为IPV4的地址数量有限,中国分到的还比较少,所以非常紧缺。 一个解决方案就是在局域网来建立一个内部的网…...
每日面试实录·携程·社招·JAVA
📍面试公司:携程 👜面试岗位:后端开发工程师(社招) 🕐面试时长:约 50 分钟 🔄面试轮次:第 1 轮技术面 ✨面试整体节奏: 这场携程的社招 Java 一面…...
Redis增删改查
### 进入redis控制台 redis-cli --raw #加上raw,防止中文乱码### 增 127.0.0.1:6379> LPUSH list0 "hello" #增加一个list 1 127.0.0.1:6379> LRANGE list0 0 -1 #查看list hello### 删 127.0.0.1:6379> DEL list0 #删除list 1 127.0.0.1:6379> LRANG…...
机器学习 Day12 集成学习简单介绍
1.集成学习概述 1.1. 什么是集成学习 集成学习是一种通过组合多个模型来提高预测性能的机器学习方法。它类似于: 超级个体 vs 弱者联盟 单个复杂模型(如9次多项式函数)可能能力过强但容易过拟合 组合多个简单模型(如一堆1次函数)可以增强能力而不易过拟合 集成…...
学习笔记十九——Rust多态
🧩 Rust 多态终极通俗指南 📚 目录导航 多态一句话概念静态分派 vs 动态分派——根本差异参数化多态(泛型) 3.1 函数里的泛型 3.2 结构体里的泛型 3.3 方法里的泛型 3.4 枚举里的泛型Ad hoc 多态(特例多态࿰…...
交换机与路由器的主要区别:深入分析其工作原理与应用场景
在现代网络架构中,交换机和路由器是两种至关重要的设备。它们在网络中扮演着不同的角色,但很多人对它们的工作原理和功能特性并不十分清楚。本文将深入分析交换机与路由器的主要区别,并探讨它们的工作原理和应用场景。 一、基本定义 1. 交换…...
【Oracle专栏】Oracle中的虚拟列
Oracle相关文档,希望互相学习,共同进步 风123456789~-CSDN博客 1.背景 在EXP方式导出时,发现 出现如下提示 EXP-00107: virtual column 不支持,因此采用expdp方式导出。于是本文针对oracle虚拟列进行简单介绍。 2. 相…...
2020 年 7 月大学英语四级考试真题(组合卷)——解析版
🏠个人主页:fo安方的博客✨ 💂个人简历:大家好,我是fo安方,目前中南大学MBA在读,也考取过HCIE Cloud Computing、CCIE Security、PMP、CISP、RHCE、CCNP RS、PEST 3等证书。🐳 &…...
大语言模型的训练、微调及压缩技术
The rock can talk — not interesting. The rock can read — that’s interesting. (石头能说话,不稀奇。稀奇的是石头能读懂。) ----硅谷知名创业孵化器 YC 的总裁 Gar Tan 目录 1. 什么是大语言模型? 2. 语言建模ÿ…...
NEAT 算法解决 Lunar Lander 问题:从理论到实践
NEAT 算法解决 Lunar Lander 问题:从理论到实践 0. 前言1. 定义环境2. 配置 NEAT3. 解决 Lunar lander 问题小结系列链接0. 前言 在使用 NEAT 解决强化学习问题一节所用的方法只适用于较简单的强化学习 (reinforcement learning, RL) 环境。在更复杂的环境中使用同样的进化解…...
firewall指令
大家好,今天我们继续来了解服务管理,来看看打开或关闭指定端口,那么话不多说,开始吧. 1.打开或者关闭指定端口 在真正的生产环境,往往需要防火墙,但问题来了,如果我们把防火墙打开,那么外部请求数据包就不能跟服务器监听通讯,这时,需要打开指定的端口,比如80,22,8080等. 2.fi…...
【MySQL】MySQL表的增删改查(CRUD) —— 上篇
目录 MySQL表的增删改查(CRUD) 1. 新增(Create)/插入数据 1.1 单行数据 全列插入 insert into 表名 values(值, 值......); 1.2 单行数据 指定列插入 1.3 多行数据 指定列插入 1.4 关于时间日期(datetime&am…...
STM32的三种启动方式
目录 一、从主闪存存储器启动(Main Flash Memory) 二、从系统存储器启动(System Memory) 三、从内置SRAM启动(Embedded SRAM) 一、从主闪存存储器启动(Main Flash Memory) >&g…...
软考高级系统架构设计师-第15章 知识产权与标准化
【本章学习建议】 根据考试大纲,本章主要考查系统架构设计师单选题,预计考3分左右,较为简单。 15.1 标准化基础知识 1. 标准的分类 分类 内容 国际标准(IS) 国际标准化组织(ISO)、国际电工…...
Spring Boot 整合 DeepSeek 实现AI对话 (保姆及教程)
文章目录 文章目录 前言 一、创建 spring boot 工程 二、申请key 三、修改配置文件 application.properties 四、编写控制器(controller) 五、运行调试 前言 提示:随着人工智能的不断发展,ai这门技术也越来越重要,很多…...
Java File 类详解
Java File 类详解 File 类是 Java 中用于表示文件和目录路径名的抽象类,位于 java.io 包中。它提供了丰富的 API,用于操作文件系统,包括创建、删除、重命名、查询文件属性等功能。 1. File 类核心知识点 (1)构造方法…...
通过特定协议拉起 electron 应用
在 Android 通过 sheme 协议可以拉起其他应用。 electron 应用也可以通过类似特定协议被拉起。 在同时有 web、客户端的应用里,可以通过这种方式在 web 拉起客户端。 支持拉起客户端 const PROTOCOL xxxif (process.defaultApp) {// 这里是开发环境,有…...
前端与传统接口的桥梁:JSONP解决方案
1.JSONP原理 1.1.动态脚本注入 说明:通过创建 <script> 标签绕过浏览器同源策略 1.2.回调约定 说明:服务端返回 函数名(JSON数据) 格式的JS代码 1.3.自动执行 说明:浏览器加载脚本后立即触发前端预定义的回调函数(现代开…...
Vue3中provide和inject数据修改规则
在 Vue3 中,通过 inject 接收到的数据是否可以直接修改,取决于 provide 提供的值的类型和响应式处理方式: 1. 若提供的是普通值(非响应式数据) javascript 复制 // 父组件 provide(staticValue, 123); 子组件修改行…...
Mac-VScode-C++环境配置
mac上自带了clang所以不是必须下载Homebrew 下面是配置文件(注释记得删一下) package.json {"name": "git-base","displayName": "%displayName%","description": "%description%",&quo…...
Linux 文件系统目录结构详解
Linux 文件系统目录结构详解 Linux 文件系统遵循 Filesystem Hierarchy Standard (FHS) 标准,定义了各个目录的用途和文件存放规则。无论是开发者、运维工程师还是普通用户,理解这些目录的作用都至关重要。本文将全面解析 Linux 的目录结构,…...
编码器---正交编码器
一、正交编码器定义与核心作用 正交编码器(Orthogonal Encoder),又称增量式编码器,是一种通过输出两路相位差90的脉冲信号(A相、B相)来测量旋转角度、速度和方向的传感器。其核心优势是通过A/B相的脉冲顺序…...
Java Streams 使用教程
简介 Stream 是 Java 8 引入的一个 函数式编程特性,可以让我们用声明式的方式操作集合(如 List、Set、Map 等)。 核心作用是: 从集合中提取数据(流) 对数据做中间操作(filter/map/sort...&am…...
1001: 自由落体的计算
题目描述 一球从m米高度自由下落,每次落地后返回原高度的一半,再落下。 求它在第n次触地时会反弹多高?直到第n次触地时共经过多少米? 输入 一行,包含两个数m, n 其中0 < m < 1,000,000,000 0 < n < 1,000,000,000 输…...
开发环境解决浏览器层面跨域问题
适用于开发环境临时调试等情况 新建一个 Chrome 的快捷方式,目标后面跟上: –disable-web-security --disable-gpu --user-data-dir%LOCALAPPDATA%\Google\chromeTemp 打开后会给出不安全的提示...
