十大排序算法之线性时间非比较类排序
线性时间非比较类排序
线性时间的算法执行效率也较高,从时间占用上看,线性时间非比较类排序要优于非线性时间排序,但其空间复杂度较非线性时间排序要大一些。因为线性时间非比较类排序算法会额外申请一定的空间进行分配排序,这也是它的典型特点——以空间换时间。而且,线性时间非比较类排序对待排序元素的要求较为严格,如计数排序要求待排序序列的差值范围不能太大,桶排序要求元素的分布要尽量均匀等。
线性时间非比较类排序的优势和局限性
线性时间算法的高效性
线性时间比较类排序算法具有较高的执行效率。相对于非线性时间排序算法,线性时间算法在时间占用上更为优越。它们能够在O(n)的时间复杂度内完成排序,这意味着算法的执行时间随着待排序元素数量的增加而线性增长。这使得线性时间算法成为处理大规模数据集的理想选择,能够快速有效地完成排序任务。
以空间换时间的策略
线性时间比较类排序算法常常以空间换时间的策略来提升排序性能。这些算法会额外申请一定的空间来进行元素分配和排序操作。例如,计数排序和桶排序都需要额外的空间用于分配元素。虽然这增加了空间复杂度,但却能够在时间复杂度上获得显著的提升。以空间换时间的策略使得线性时间比较类排序算法在某些场景下非常适用。
限制和要求
线性时间比较类排序算法对待排序元素有一定的限制和要求。例如,计数排序要求待排序序列的差值范围不能太大,否则会导致额外的空间消耗。桶排序则要求元素的分布尽量均匀,以充分利用桶的优势。因此,在选择线性时间比较类排序算法时,需要根据待排序数据的特点来确定算法的适用性。
例子
在Java编程语言中,实现线性时间比较类排序算法可以帮助我们更直观地理解其工作原理和优势。以下以基数排序(Radix Sort)为例,这是一种线性时间复杂度的非比较类排序算法,适用于整数排序且对数值范围有一定要求。
public class RadixSort {// 基数排序函数public static void radixsort(int[] arr) {if (arr == null || arr.length == 0)return;int max = Arrays.stream(arr).max().getAsInt(); // 找出数组中的最大值for (int exp = 1; max / exp > 0; exp *= 10) { // 按照每一位进行计数排序countingSort(arr, exp);}}// 计数排序辅助函数private static void countingSort(int[] arr, int exp) {int n = arr.length;int[] output = new int[n]; // 输出数组int[] count = new int[10]; // 计数数组Arrays.fill(count, 0);// 计算每个位上出现的次数for (int i = 0; i < n; i++) {count[(arr[i] / exp) % 10]++;}// 将计数数组转换为前缀和,便于计算输出位置for (int i = 1; i < 10; i++) {count[i] += count[i - 1];}// 根据计数数组将元素放到正确的位置for (int i = n - 1; i >= 0; i--) {output[count[(arr[i] / exp) % 10] - 1] = arr[i];count[(arr[i] / exp) % 10]--;}// 将临时数组复制回原数组System.arraycopy(output, 0, arr, 0, n);}// 测试代码public static void main(String[] args) {int[] array = {170, 45, 75, 90, 802, 24, 2, 66};radixsort(array);System.out.println(Arrays.toString(array));}
}
上面这段Java代码展示了基数排序的基本实现,它首先找到数组中的最大值来确定需要处理的位数,然后逐个按照每一位进行计数排序。虽然基数排序的空间复杂度相对较高,但它能在线性时间内完成排序,尤其对于大规模整数排序场景具有很高的实用价值。
除了基数排序,还有一种线性时间非比较类排序算法——桶排序(Bucket Sort),它适用于待排序元素在一定范围内且分布均匀的情况。桶排序的思想是将数组中的元素分到有限数量的“桶”中,然后对每个桶分别进行排序,最后按顺序合并所有桶中的元素。
以下是Java实现桶排序的基本示例:
public class BucketSort {// 桶排序函数public static void bucketSort(int[] arr, int bucketSize) {if (arr == null || arr.length == 0)return;int minValue = Arrays.stream(arr).min().getAsInt();int maxValue = Arrays.stream(arr).max().getAsInt();// 创建桶List<List<Integer>> buckets = new ArrayList<>();for (int i = 0; i <= maxValue - minValue; i += bucketSize) {buckets.add(new ArrayList<>());}// 将元素分配到各个桶中for (int num : arr) {int index = (num - minValue) / bucketSize;buckets.get(index).add(num);}// 对每个桶进行排序,这里使用插入排序作为子排序算法for (List<Integer> bucket : buckets) {Collections.sort(bucket);}// 合并所有已排序的桶int index = 0;for (List<Integer> bucket : buckets) {for (Integer num : bucket) {arr[index++] = num;}}}// 测试代码public static void main(String[] args) {int[] array = {5, 3, 8, 1, 9, 6, 7, 2, 4};bucketSort(array, 3);System.out.println(Arrays.toString(array));}
}
在上面这段Java代码中,首先计算出数组的最小值和最大值以确定桶的数量,并初始化桶列表。接着遍历输入数组,根据元素值将其放入对应的桶中。之后对每个桶内部采用插入排序或其他适合的小规模排序算法进行排序。最后,按照桶的顺序合并所有已排序的桶,从而得到最终排序结果。
虽然桶排序在理想情况下可以达到线性时间复杂度,但其性能取决于输入数据的分布情况以及所选桶大小等因素。如果数据分布不均匀或者桶大小选择不当,可能会导致实际运行效率下降。
上面的两个例子会在后面的文章里详细讲解
总结
线性时间非比较类排序算法具有高效的执行效率和较低的时间复杂度,适用于处理大规模数据集的排序任务。它们以空间换时间的策略,在一定的限制和要求下,能够快速有效地完成排序操作。然而,需要根据待排序数据的特点来选择合适的算法,以充分发挥线性时间比较类排序算法的优势。
相关文章:
十大排序算法之线性时间非比较类排序
线性时间非比较类排序 线性时间的算法执行效率也较高,从时间占用上看,线性时间非比较类排序要优于非线性时间排序,但其空间复杂度较非线性时间排序要大一些。因为线性时间非比较类排序算法会额外申请一定的空间进行分配排序,这也…...
容器基础:Docker 镜像如何保证部署的一致性?
Docker 镜像如何通过固化基础环境、固化依赖性和固化软件启动流程保证部署的一致性 Docker 镜像通过以下三个方面保证部署的一致性: 1. 固化基础环境: 镜像包含构建应用程序所需的所有环境依赖项,例如操作系统、库和工具。构建镜像时,所有…...

爪哇部落算法组2024新生赛热身赛题解
第一题(签到): 1、题意: 2、题解: 我们观察到happynewyear的长度是12个字符,我们直接从前往后遍历0到n - 12的位置(这里索引从0开始),使用C的substr()函数找到以i开头的长度为12的字…...
1123. 铲雪车(欧拉回路)
活动 - AcWing 随着白天越来越短夜晚越来越长,我们不得不考虑铲雪问题了。 整个城市所有的道路都是双向车道,道路的两个方向均需要铲雪。因为城市预算的削减,整个城市只有 1 辆铲雪车。 铲雪车只能把它开过的地方(车道)的雪铲干…...

网络协议与攻击模拟_15FTP协议
了解FTP协议 在Windows操作系统上使用serv-U软件搭建FTP服务 分析FTP流量 一、FTP协议 1、FTP概念 FTP(文件传输协议)由两部分组成:客户端/服务端(C/S架构) 应用场景:企业内部存放公司文件、开发网站时利…...

「效果图渲染」效果图与3D影视动画渲染平台
效果图渲染和3D影视动画渲染都是视觉图像渲染的领域应用。效果图渲染主要服务于建筑、室内设计和产品设计等行业,这些领域通常对视觉呈现的精度和细节有较高要求。与之相比,3D影视动画渲染则普遍应用于电影、电视、视频游戏和广告等媒体领域,…...

Blender_查看版本
Blender_查看版本 烦人的烦恼,没找见哪儿可以查看版本? 算是个隐蔽的角落!...
node.js 读目录.txt文件,用 xml2js 转换为json数据,生成jstree所需的文件
请参阅:java : pdfbox 读取 PDF文件内书签 请注意:书的目录.txt 编码:UTF-8,推荐用 Notepad 转换编码。 npm install elementtree ; npm install xml2js ; node.js 用 elementtree读目录.txt文件,用 xml2js 转换为…...

【Docker】02 镜像管理
文章目录 一、Images镜像二、管理操作2.1 搜索镜像2.1.1 命令行搜索2.1.2 页面搜索2.1.3 搜索条件 2.2 下载镜像2.3 查看本地镜像2.3.1 docker images2.3.2 --help2.3.3 repository name2.3.4 --filter2.3.5 -q2.3.6 --format 2.4 给镜像打标签2.5 推送镜像2.6 删除镜像2.7 导出…...

了解海外云手机的多种功能
随着社会的高度发展,海外云手机成为商家不可或缺的工具,为企业出海提供了便利的解决方案。然而,谈及海外云手机,很多人仍不了解其强大功能。究竟海外云手机有哪些功能,可以为我们做些什么呢? 由于国内电商竞…...

白酒:自动化生产线的优势与实践
随着科技的进步,自动化生产线在各行各业的应用越来越广泛。云仓酒庄的豪迈白酒在生产过程中,也积极引入自动化生产线,以提升生产效率、品质和安全性。 首先,自动化生产线能够显著提高生产效率。传统的手工生产线在生产过程中容易受…...

用HTML5实现灯笼效果
本文介绍了两种实现效果:一种使用画布(canvas)标签/元素,另一种不用画布(canvas)标签/元素主要使用CSS实现。 使用画布(canvas)标签/元素实现,下面,在画布上…...
Postgresql源码(120)事务XID分配与主备XID同步
参考 《Postgresql源码(25)子事务可见性判断和性能问题》 XID获取顶层入口 函数:AssignTransactionId static void AssignTransactionId(TransactionState s) {...优先给没有事务ID的父事务分配 确保父事务有 XID,以便子事务总是…...
B2077 角谷猜想(洛谷)
题目描述 所谓角谷猜想,是指对于任意一个正整数,如果是奇数,则乘 33 加 11,如果是偶数,则除以 22,得到的结果再按照上述规则重复处理,最终总能够得到 11。如,假定初始整数为 55&…...

排序算法---归并排序
原创不易,转载请注明出处。欢迎点赞收藏~ 归并排序是一种常见的排序算法,它采用了分治的思想。它将一个待排序的数组递归地分成两个子数组,分别对两个子数组进行排序,然后将排好序的子数组合并成一个有序数组。 具体的归并排序过…...

[WUSTCTF2020]朴实无华(特详解)
一开始说header出问题了 就先dirsaerch扫一遍 发现robot.txt 访问一下 去看看,好好好,肯定不是得 他一开始说header有问题,不妨抓包看看,果然有东西 访问看看,乱码修复一下,在之前的博客到过 <img src…...

下载已编译的 OpenCV 包在 Visual Studio 下实现快速配置
自己编译 OpenCV 挺麻烦的,配置需要耗费很长时间,编译也需要很长时间,而且无法保证能全部编译通过。利用 OpenCV 官网提供的已编译的 OpenCV 库可以节省很多时间。下面介绍安装配置方法。 1. OpenCV 官网 地址是:https://opencv…...

【Linux系统学习】3.Linux用户和权限
Linux用户和权限 1.认知root用户 1.1 root用户(超级管理员) 无论是Windows、MacOS、Linux均采用多用户的管理模式进行权限管理。 在Linux系统中,拥有最大权限的账户名为:root(超级管理员) 而在前期&#…...

视频美颜SDK开发指南:从入门到精通的技术实践
美颜SDK是一种强大的工具,它不仅仅可以让用户在实时视频中获得光滑的肌肤和自然的妆容,从简单的滤镜到复杂的人脸识别,美颜SDK涵盖了广泛的技术领域。 一、美颜SDK的基本原理 美颜SDK包括图像处理、人脸检测和识别、滤镜应用等方面。掌握这些…...

Electron基本介绍
Electron基本介绍 Electron 官方网站:https://www.electronjs.org/zh/ Electron安装方法:npm install electron -g 全局安装 Electron简介:Electron提供了丰富的本地(操作系统)API,使你能够使用纯JavaScr…...
Java 语言特性(面试系列2)
一、SQL 基础 1. 复杂查询 (1)连接查询(JOIN) 内连接(INNER JOIN):返回两表匹配的记录。 SELECT e.name, d.dept_name FROM employees e INNER JOIN departments d ON e.dept_id d.dept_id; 左…...

多模态2025:技术路线“神仙打架”,视频生成冲上云霄
文|魏琳华 编|王一粟 一场大会,聚集了中国多模态大模型的“半壁江山”。 智源大会2025为期两天的论坛中,汇集了学界、创业公司和大厂等三方的热门选手,关于多模态的集中讨论达到了前所未有的热度。其中,…...

css实现圆环展示百分比,根据值动态展示所占比例
代码如下 <view class""><view class"circle-chart"><view v-if"!!num" class"pie-item" :style"{background: conic-gradient(var(--one-color) 0%,#E9E6F1 ${num}%),}"></view><view v-else …...

【WiFi帧结构】
文章目录 帧结构MAC头部管理帧 帧结构 Wi-Fi的帧分为三部分组成:MAC头部frame bodyFCS,其中MAC是固定格式的,frame body是可变长度。 MAC头部有frame control,duration,address1,address2,addre…...

聊聊 Pulsar:Producer 源码解析
一、前言 Apache Pulsar 是一个企业级的开源分布式消息传递平台,以其高性能、可扩展性和存储计算分离架构在消息队列和流处理领域独树一帜。在 Pulsar 的核心架构中,Producer(生产者) 是连接客户端应用与消息队列的第一步。生产者…...

DBAPI如何优雅的获取单条数据
API如何优雅的获取单条数据 案例一 对于查询类API,查询的是单条数据,比如根据主键ID查询用户信息,sql如下: select id, name, age from user where id #{id}API默认返回的数据格式是多条的,如下: {&qu…...

【Java_EE】Spring MVC
目录 Spring Web MVC 编辑注解 RestController RequestMapping RequestParam RequestParam RequestBody PathVariable RequestPart 参数传递 注意事项 编辑参数重命名 RequestParam 编辑编辑传递集合 RequestParam 传递JSON数据 编辑RequestBody …...
Java多线程实现之Thread类深度解析
Java多线程实现之Thread类深度解析 一、多线程基础概念1.1 什么是线程1.2 多线程的优势1.3 Java多线程模型 二、Thread类的基本结构与构造函数2.1 Thread类的继承关系2.2 构造函数 三、创建和启动线程3.1 继承Thread类创建线程3.2 实现Runnable接口创建线程 四、Thread类的核心…...

安宝特案例丨Vuzix AR智能眼镜集成专业软件,助力卢森堡医院药房转型,赢得辉瑞创新奖
在Vuzix M400 AR智能眼镜的助力下,卢森堡罗伯特舒曼医院(the Robert Schuman Hospitals, HRS)凭借在无菌制剂生产流程中引入增强现实技术(AR)创新项目,荣获了2024年6月7日由卢森堡医院药剂师协会࿰…...

qt+vs Generated File下的moc_和ui_文件丢失导致 error LNK2001
qt 5.9.7 vs2013 qt add-in 2.3.2 起因是添加一个新的控件类,直接把源文件拖进VS的项目里,然后VS卡住十秒,然后编译就报一堆 error LNK2001 一看项目的Generated Files下的moc_和ui_文件丢失了一部分,导致编译的时候找不到了。因…...