时间复杂度为 O(n^2) 的排序算法 | 京东物流技术团队

对于小规模数据,我们可以选用时间复杂度为 O(n2) 的排序算法。因为时间复杂度并不代表实际代码的执行时间,它省去了低阶、系数和常数,仅代表的增长趋势,所以在小规模数据情况下, O(n2) 的排序算法可能会比 O(nlogn) 的排序算法执行效率高。不过随着数据规模增大, O(nlogn) 的排序算法是不二选择。本篇我们主要对 O(n2) 的排序算法进行介绍,在介绍之前,我们先了解一下算法特性:

  • 算法特性:

    • 稳定性:经排序后,若等值元素之间的相对位置不变则为稳定排序算法,否则为不稳定排序算法

    • 原地排序:是否借助额外辅助空间

    • 自适应性: 自适应性排序受输入数据的影响,即最佳/平均/最差时间复杂度不等,而非自适应排序时间复杂度恒定

本篇我们将着重介绍插入排序,选择排序和冒泡排序了解即可。

插入排序

插入排序的工作方式像整理手中的扑克牌一样,即不断地将每一张牌插入到其他已经有序的牌中适当的位置。

插入排序的当前索引元素左侧的所有元素都是有序的:若当前索引为 i,则 [0, i - 1] 区间内的元素始终有序,这种性质被称为循环不变式,即在第一次迭代、迭代过程中和迭代结束时,这种性质始终保持不变。

不过,这些有序元素的索引位置暂时不能确定,因为它们可能需要为更小的元素腾出空间而向右移动。插入排序的代码实现如下:

    private void sort(int[] nums) {for (int i = 1; i < nums.length; i++) {int base = nums[i];int j = i - 1;while (j >= 0 && nums[j] > base) {nums[j + 1] = nums[j--];}nums[j + 1] = base;}}

它的实现逻辑是取未排序区间中的某个元素为基准数base,将base与其左侧已排序区间元素依次比较大小,并"插入"到正确位置。插入排序对部分有序(数组中每个元素距离它的最终位置都不远或数组中只有几个元素的位置不正确等情况)的数组排序效率很高。事实上,当逆序很少或数据量不大(n2和nlogn比较接近)时,插入排序可能比其他任何排序算法都要快,这也是一些编程语言的内置排序算法在针对小数据量数据排序时选择使用插入排序的原因。

算法特性:

  • 空间复杂度:O(1)

  • 原地排序

  • 稳定排序

  • 自适应排序:当数组为升序时,时间复杂度为 O(n);当数组为降序时,时间复杂度为 O(n2)

希尔排序

插入排序对于大规模乱序数组排序很慢,因为它只会交换相邻的元素,所以元素只能一步步地从一端移动到另一端,如果最小的元素恰好在数组的最右端,要将它移动到正确的位置需要移动 N - 1 次。

希尔排序是基于插入排序改进的排序算法,它可以交换不相邻的元素以对数组的局部进行排序,并最终用插入排序将局部有序的数组排序。它的思想是使数组中间隔为 h 的元素有序(h 有序数组),如下图为间隔为 4 的有序数组:

希尔排序.jpg

排序之初 h 较大,这样我们能将较小的元素尽可能移动到靠近左端的位置,为实现更小的 h 有序创造便利,最后一次循环时 h 为 1,便是我们熟悉的插入排序。这就是希尔排序的过程,代码实现如下:

    private void sort(int[] nums) {int N = nums.length;int h = 1;while (h < N / 3) {h = 3 * h + 1;}while (h >= 1) {for (int i = h; i < N; i++) {int base = nums[i];int j = i - h;while (j >= 0 && nums[j] > base) {nums[j + h] = nums[j];j -= h;}nums[j + h] = base;}h /= 3;}}

希尔排序更高效的原因是它权衡了子数组的规模和有序性,它也可以用于大型数组。排序之初,各个子数组都很短,排序之后子数组都是部分有序的,这两种情况都很适合插入排序。


选择排序

选择排序的实现非常简单:每次选择未排序数组中的最小值,将其放到已排序区间的末尾,代码实现如下:

    private void sort(int[] nums) {for (int i = 0; i < nums.length; i++) {int min = i;for (int j = i + 1; j < nums.length; j++) {if (nums[j] < nums[min]) {min = j;}}swap(nums, i, min);}}private void swap(int[] nums, int i, int j) {int temp = nums[i];nums[i] = nums[j];nums[j] = temp;}

算法特性:

  • 空间复杂度:O(1)

  • 原地排序

  • 非稳定排序:会改变等值元素之间的相对位置

  • 非自适应排序:最好/平均/最坏时间复杂度均为 O(n2)

冒泡排序

冒泡排序通过连续地比较与交换相邻元素实现排序,每轮循环会将未被排序区间内的最大值移动到数组的最右端,这个过程就像是气泡从底部升到顶部一样,代码实现如下:

    public void sort(int[] nums) {for (int i = nums.length - 1; i > 0; i--) {// 没有发生元素交换的标志位boolean flag = true;for (int j = 0; j < i; j++) {if (nums[j] > nums[j + 1]) {swap(nums, j, j + 1);flag = false;}}if (flag) {break;}}}private void swap(int[] nums, int i, int j) {int temp = nums[i];nums[i] = nums[j];nums[j] = temp;}

算法特性:

  • 空间复杂度:O(1)

  • 原地排序

  • 稳定排序

  • 自适应排序:经过优化后最佳时间复杂度为 O(n)


巨人的肩膀

  • 《算法导论 第三版》第 2.1 章

  • 《算法 第四版》第 2.1 章

  • 《Hello 算法》第 11 章

  • 排序算法-希尔排序

作者:京东物流 王奕龙

来源:京东云开发者社区 自猿其说Tech 转载请注明来源

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/198200.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Stable Diffusion教程:4000字说清楚图生图

原文&#xff1a;Stable Diffusion教程&#xff1a;4000字说清楚图生图 - 知乎 目录 收起 基本使用 涂鸦绘制 局部绘制 局部绘制&#xff08;涂鸦蒙版&#xff09; 局部绘制&#xff08;上传蒙版&#xff09; 批量处理 总结 资源下载 “图生图”是 Stable Diffusion…

【Android知识笔记】架构专题(三)

如何用工程手段,提高写代码的生产力?(元编程) 即如何写同样多的代码,花费更少的时间?如何自动生成代码,哪种代码可以被自动生成?哪些环节能够作为自动生成代码的切入点? 代码自动生成技术 代码自动生成,指的并不是让计算机凭自己的意愿生成代码。而是让预先实现好…

windows运行orb-slam3遇到的问题

windows版代码地址&#xff1a;https://github.com/melhashash/orbslam3-windows 编译完成&#xff0c;出现初始化不成功的现象。 问题一&#xff1a; 相机参数中没有相机类型&#xff0c;导致畸变参数初始化失败。 GrabImageRGBD中frame对象实例化时&#xff0c;缺少相机参数…

【Windows】永久屏蔽系统更新

永久关闭电脑更新服务 操作思路&#xff1a; 第一步 winR 输入 services.msc 回车 进入服务管理窗口第二步 进入窗口后 找到 w 开头的文件夹 并找到Windows Update 双击打开 Windows Update 将启动类型&#xff08;E&#xff09; 改为禁用 上方的 “常规” “登录” “恢…

SNP推出新Glue软件Saas版本,助力云数据集成

最新Glue版本可作为软件即服务(SaaS)应用程序使用SAP数据和非SAP数据源之间的云原生集成大大简化了客户的企业数据集成SNP Glue通过应对AI和大数据计划中的关键挑战来增强云数据集成的价值 德国&#xff0c;海德堡 —— 2023年11月29日&#xff0c;作为SAP环境中数字化转型、自…

Vue学习笔记-<router-link>的replace的属性

router-link的replace属性 作用&#xff1a;控制路由跳转时操作浏览器历史记录的模式 浏览器的历史记录有两种写入方式&#xff1a;push和replace&#xff0c;其中push是追加历史记录&#xff08;将浏览的url请求入栈&#xff09;&#xff0c;replace则是替换当前记录。路由跳…

如何计算 ChatGPT 的 Tokens 数量?

一、基本介绍 随着人工智能大模型技术的迅速发展&#xff0c;一种创新的计费模式正在逐渐普及&#xff0c;即以“令牌”&#xff08;Token&#xff09;作为衡量使用成本的单位。那么&#xff0c;究竟什么是Token呢&#xff1f; Token 是一种将自然语言文本转化为计算机可以理…

容器重启后,Conda文件完整保存(虚拟环境、库包),如何重新安装conda并迁移之前的虚拟环境

Vim安装 容器重启后默认是vi&#xff0c;升级vim&#xff0c;执行命令 apt install -y vim安装 Anaconda 1. 下载Anaconda 其他版本请查看Anaconda官方库 wget https://mirrors.bfsu.edu.cn/anaconda/archive/Anaconda3-2023.03-1-Linux-x86_64.sh --no-check-certificate…

【DBeaver】驱动添加-Hive和星环

驱动 Hive驱动 hive驱动可以直接去官网下载官网地址&#xff0c;填一下个人信息。 如果想直接下载可以去我上次的资源下地址&#xff0c;需要用zip解压。 星环驱动 星环驱动是我第一次接触&#xff0c;是国产的基于开源Hive驱动自研的产品&#xff0c;我看到官网上有很多类…

[leetcode ~二叉树] 模版

文章目录 1. 左叶子之和2. 翻转二叉树 E 1. 左叶子之和 :::details 给定二叉树的根节点 root &#xff0c;返回所有左叶子之和。 示例 1&#xff1a; 输入: root [3,9,20,null,null,15,7] 输出: 24 解释: 在这个二叉树中&#xff0c;有两个左叶子&#xff0c;分别是 9 和 15&…

跨浏览器测试:如何确保你的应用在各种浏览器上都能正常运行

在当今的互联网时代&#xff0c;浏览器已成为我们获取信息、与他人交流、工作和娱乐的主要工具。然而&#xff0c;不同的浏览器、不同的版本和不同的操作系统可能会对你的应用造成不同的影响&#xff0c;可能使其表现出各种不同的行为和问题。为了确保你的应用能在各种浏览器环…

GaussDB数据库SQL系列-序列的使用

目录 一、前言 二、GaussDB数据库中的序列 1、语法(CREATE SEQUENCE) 2、注意事项 三、GaussDB数据库中的示例 1、示例一&#xff1a;创建普通序列 2、示例二&#xff1a;创建与表关联的序列 四、小结 一、前言 在数据库管理中&#xff0c;序列&#xff08;SEQUENCE&a…

Nginx的使用

Nginx的使用 一、配置前端项目访问二、配置SSL证书1、正常配置2、配置报错 三、配置域名反向代理1、简单代理2、带参数代理3、指定后缀域名跳转4、访问反向代理域名的静态资源5、配置静态资源访问&#xff08;1&#xff09;、将域名配置到小程序&#xff0c;获得TXT文件&#x…

leetcode:对称二叉树

题目描述 题目链接&#xff1a;101. 对称二叉树 - 力扣&#xff08;LeetCode&#xff09; 题目分析 题目中说至少存在一个节点&#xff0c;所以我们只需要对比左右子树 写一个子函数对比左右子树&#xff1a;用递归的思路&#xff0c;左子树的左子树和右子树的右子树对比&…

2024 年甘肃省职业院校技能大赛中职组 电子与信息类“网络安全”赛项竞赛样题-B

2024 年甘肃省职业院校技能大赛中职组 电子与信息类“网络安全”赛项竞赛样题-B 目录 2024 年甘肃省职业院校技能大赛中职组 电子与信息类“网络安全”赛项竞赛样题-B 需要环境或者解析可以私信 &#xff08;二&#xff09;A 模块基础设施设置/安全加固&#xff08;200 分&…

使用Python Flask搭建Web问答应用程序并发布到公网远程访问

使用Python Flask搭建web问答应用程序框架&#xff0c;并发布到公网上访问 文章目录 使用Python Flask搭建web问答应用程序框架&#xff0c;并发布到公网上访问前言1. 安装部署Flask并制作SayHello问答界面2. 安装Cpolar内网穿透3. 配置Flask的问答界面公网访问地址4. 公网远程…

打开游戏提示缺少(或找不到)XINPUT1_3.DLL怎么解决

在电脑使用过程中&#xff0c;我们可能会遇到一些错误提示&#xff0c;其中之一就是xinput1_3.dll丢失。那么&#xff0c;xinput1_3.dll是什么文件&#xff1f;它对电脑有什么影响&#xff1f;本文将详细介绍xinput1_3.dll丢失的原因以及五个详细的解决方法&#xff0c;帮助大家…

帮企多城市分站系统源码+关键词排名优化推广 附带完整的搭建教程

随着市场竞争的加剧&#xff0c;企业对于网络营销的需求越来越多元化。传统的单一网站已经无法满足企业在网络营销方面的需求&#xff0c;因此我们需要开发一套多城市分站系统&#xff0c;以满足企业在不同地区、不同行业的需求。同时&#xff0c;我们还结合了关键词排名优化推…

外包干了2个月,技术明显退步了...

先说一下自己的情况&#xff0c;大专生&#xff0c;19年通过校招进入广州某软件公司&#xff0c;干了接近5年的功能测试&#xff0c;今年11月份&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了四年的功能测…

UE4 双屏分辨率设置

背景&#xff1a; 做了一个UI 应用&#xff0c;需要在双屏上进行显示。 分辨率如下&#xff1a;3840*1080&#xff1b; 各种折腾&#xff0c;其实很简单&#xff1a; 主要是在全屏模式的时候 一开始没有选对&#xff0c;双屏总是不稳定。 全屏模式改成&#xff1a;Windows 之…