排序-java(插入排序和选择排序)

一,分类

主要的排序大致分为以下几类:

1,插入排序,又分为直接插入排序和希尔排序

2,选择排序,又分为选择排序和堆排序

3,交换排序,又分为冒泡排序和快速排序

4,归并排序

二,插入排序

1,直接插入排序

一个数组,定义两个变量i和j,i从数组的第二个元素开始往后遍历,直到数组结束。每次遍历把下标为i的值储存到临时变量tmp中。与此同时,j=i-1,j往前遍历,每一次下标j对应的值都与tmp进行比较,如果j的对应值大于tmp,则arr【j+1】=arr【j】,如果小于tmp的值,则直接跳出循环。因为如果遇到小于tmp的值,则这个值前面的数据肯定都小于tmp,这时就可以直接将tmp的值放入arr【j+1】里面。

public static void insertSort(int[] array){for (int i = 1; i < array.length; i++) {int tmp=array[i];int j = i-1;for (; j >=0 ; j--) {if (tmp<array[j]){array[j+1]=array[j];}else {break;}}array[j+1]=tmp;}
}

简易图:

总结:

(1)对于直接插入排序,越有序,排序越快,所以如果一组数据趋于有序时,可以优先选择直接插入排序

(2)时间复杂度:O(n^2)

(3)空间复杂度:O(1)

(4)稳定性:稳定

注:稳定性指:

2,希尔排序

希尔排序时对直接插入排序的优化。其又称为缩小增量的排序,将数据分成不同的组,然后将每一组的数据进行直接插入排序,然后将组数不断减少,直到减少到一,每减少一次就排一次序。当组数多的时候每组的数据少,所以时间复杂度小,当组数小的时候,虽然数据比较多,但是数据是趋于有序的,所以直接插入排序的时间复杂度也较低,综上所述,这种方法的效率较高。

public static void shellSort(int[] array){int gap= array.length;while (gap>1){gap/=2;shell(array,gap);}
}
public static void shell(int []array,int gap){for (int i = gap; i < array.length; i++) {int tmp=array[i];int j = i-gap;for (; j >=0 ; j=j-gap) {if (tmp<array[j]){array[j+gap]=array[j];}else {break;}}array[j+gap]=tmp;}
}

总结:

(1) 希尔排序的时间复杂度不好计算,因为gap的取值方法很多,导致很难去计算

时间复杂度(估算):O(n*log2(n))

(2)空间复杂度:O(1)

(3)稳定性:不稳定

三,选择排序

1,选择排序

定义i和j两个变量,i从0开始遍历整个数组,定义最小值的下标变量为minIndex,当 i 每等于一个值时,minIndex=i,j就从i+1开始向后遍历,遇到array[minIndex]>array[j],就将minIndex=j从而保证这是这次 j 遍历的数据中的最小值,直到 j 遍历完整个数组后,将下标为i的值与下标为minIndex的值进行交换。从而使i的位置是这次 j 遍历的数据中的最小值。然后i++,继续寻找第二小的值放到 i 的位置……

下图为i=0时的一次遍历:

private static void swap(int[]array,int i,int j){int tmp=array[i];array[i]=array[j];array[j]=tmp;
}
public static void selectSort(int[]array){for (int i = 0; i < array.length; i++) {int minIndex=i;for (int j = i+1; j < array.length; j++) {if (array[minIndex]>array[j]){minIndex=j;}}swap(array,i,minIndex);}
}

当然我们也可以在  j  遍历的时候同时找到最小值和最大值的下标,但需要注意的是,第一次遍历之后就可以筛选出最大值和最小值,这时最小值放第一个,最大值放最后一个,第二次遍历的时候就不需要遍历头和尾了。因此每次遍历就可以挑出一对数据,最大值和最小值。所以下一次遍历就只需要从中间寻找最大值和最小值了,所以i只需要遍历一半的数据就可以完成整个排序。

public static void selectSort2(int[]array){for (int i = 0; i < array.length/2; i++) {int minIndex= i;int maxIndex= i;for (int j = i+1; j < array.length-i; j++) {if (array[j]< array[minIndex]){minIndex=j;}if (array[j]> array[maxIndex]){maxIndex=j;}}swap(array,minIndex,i);if (maxIndex==0){maxIndex=minIndex;}swap(array,maxIndex,array.length-1-i);}
}

总结:

(1) 时间复杂度:O(n^2)

(2)空间复杂度:O(1)

(3)稳定性:不稳定

2,堆排序

堆排序时首先要调整成大根堆,因为大根堆下标为0的元素一定是最大的,所以可以将第一个元素和最后一个下标的元素交换,然后将第一个元素向下调整重新调整为大根堆,调整的终点是前一次调整的数组长度-1(已经选出了最大的元素,现在需要在剩余的元素中找到第二大的,所以向下调整大范围不包括已经排好序的数据),然后然后循环上述行为。使数组中的每一个元素都得到调整从而就可以得到顺序了。

延伸说明:

调整大根堆:我们需要求出最后一个子节点的父节点,然后向前遍历,将每一个父节点就进行向下调整。

向下调整:需要知道需要调整的父节点的下标和调整的范围(如果是建立大根堆,调整的范围就是到最后一个下标),知道父亲节点后求出左子节点,然后判断是否有右子节点,如果有那么判断array[child+1]与array[child]的大小关系,如果关系是大于,那么child++,这样保证child所指向的是较大的子孩子。然后将较大的子孩子和父节点的值进行比较,如果孩子节点大于父亲节点,那么两者交换,因为如果两者交换的话,会影响被交换为子节点的节点作为父亲节点时,与它自己的子节点的大小关系,所以交换后要parent=child; child=parent*2+1;然后再次重复循环上述操作,直到孩子节点是越界,则代表调整完毕。但如果父亲节点大于孩子节点就可以直接跳出循环了,因为父子节点之间不需要交换,而子节点以下的节点本身就是调整好的所以不需要再次调整,直接跳出循环即可。

public static void siftDown(int []array,int parent,int end){int child=parent*2+1;while (child<end+1){if (child+1<=end){if (array[child+1]>array[child]){child++;}}if (array[child]>array[parent]){swap(array,child,parent);parent=child;child=parent*2+1;}else {break;}}}
public static void createBigHeap(int[]array){int child=array.length-1;int parent= (child-1)/2;while (parent>=0){siftDown(array,parent,array.length-1);parent--;}
}public static void heapSort(int []array){//调整为大根堆createBigHeap(array);int end= array.length-1;while (end>0){swap(array,0,end);end--;siftDown(array,0,end);}
}

总结:

(1) 时间复杂度:O(n*log2(n))

(2)空间复杂度:O(1)

(3)稳定性:不稳定

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

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

相关文章

springboot配置扫描生效顺序

文章目录 举例分析项目结构如下noddles-user-backend 两个配置文件noddles-user-job 配置文件noddles-user-server 配置文件问题:server和Job启动时对应加载的数据库配置为哪一个&#xff1f; 总结 在微服务架构中&#xff0c;backend模块会定义一个基础的配置文件&#xff0c;…

Report Design Analysis报告之logic level详解

目录 一、前言 二、Logic Level distribution 2.1 logic level配置 2.2 Logic Level Distribution报告 2.3 Logic Level 报告详情查看 2.4 Route Distributions 报告详情查看 2.5 示例代码 一、前言 ​在工程设计中&#xff0c;如果需要了解路径的逻辑级数&#xff0c;可…

卷积神经网络基础篇

文章目录 1、卷积层1.1、激活函数1.3、sigmoid1.4、Tanh1.5、ReLU1.6、Leaky ReLU1.7、误差计算 2、池化层3、全连接层4、CNN训练 参考链接1 参考链接2 1、卷积层 卷积层&#xff08;Convolutional layer&#xff09;&#xff0c;这一层就是卷积神经网络最重要的一个层次&…

动手学深度学习(Pytorch版)代码实践 -循环神经网络- 56门控循环单元(`GRU`)

56门控循环单元&#xff08;GRU&#xff09; 我们讨论了如何在循环神经网络中计算梯度&#xff0c; 以及矩阵连续乘积可以导致梯度消失或梯度爆炸的问题。 下面我们简单思考一下这种梯度异常在实践中的意义&#xff1a; 我们可能会遇到这样的情况&#xff1a;早期观测值对预测…

机器人动力学模型及其线性化阻抗控制模型

机器人动力学模型 机器人动力学模型描述了机器人的运动与所受力和力矩之间的关系。这个模型考虑了机器人的质量、惯性、关节摩擦、重力等多种因素&#xff0c;用于预测和解释机器人在给定输入下的动态行为。动力学模型是设计机器人控制器的基础&#xff0c;它可以帮助我们理解…

2024/7/7周报

文章目录 摘要Abstract文献阅读题目问题本文贡献问题描述图神经网络Framework实验数据集实验结果 深度学习MAGNN模型相关代码GNN为什么要用GNN&#xff1f;GNN面临挑战 总结 摘要 本周阅读了一篇用于多变量时间序列预测的多尺度自适应图神经网络的文章&#xff0c;多变量时间序…

SAP已下发EWM的交货单修改下发状态

此种情况针对EWM未接收到ERP交货单时&#xff0c;可以使用此程序将ERP交货单调整为未分配状态&#xff0c;在进行调整数据后&#xff0c;然后使用VL06I&#xff08;启用自动下发EWM配置&#xff0c;则在交货单修改保存后会立即下发EWM&#xff09;重新下发EWM系统。 操作步骤如…

3ds Max渲染曝光过度怎么办?

3dmax效果图云渲染平台——渲染100 以3ds Max 2025、VR 6.2、CR 11.2等最新版本为基础&#xff0c;兼容fp、acescg等常用插件&#xff0c;同时LUT滤镜等参数也得到了同步支持。 注册填邀请码【7788】可领30元礼包和免费渲染券哦~ 遇到3ds Max渲染过程中曝光过度的问题&#xf…

SLF4J的介绍与使用(有logback和log4j2的具体实现案例)

目录 1.日志门面的介绍 常见的日志门面 &#xff1a; 常见的日志实现&#xff1a; 日志门面和日志实现的关系&#xff1a; 2.SLF4J 的介绍 业务场景&#xff08;问题&#xff09;&#xff1a; SLF4J的作用 SLF4J 的基本介绍 日志框架的绑定&#xff08;重点&#xff09…

跨越界限的温柔坚守

跨越界限的温柔坚守 —— 郑乃馨与男友的甜蜜抉择在这个光怪陆离、瞬息万变的娱乐圈里&#xff0c;每一段恋情像是夜空中划过的流星&#xff0c;璀璨短暂。然而&#xff0c;当“郑乃馨与男友甜蜜约会”的消息再次跃入公众视野&#xff0c;它不仅仅是一段简单的爱情故事&#xf…

iOS中多个tableView 嵌套滚动特性探索

嵌套滚动的机制 目前的结构是这样的&#xff0c;整个页面是一个大的tableView, Cell 是整个页面的大小&#xff0c;cell 中嵌套了一个tableView 通过测试我们发现滚动的时候&#xff0c;系统的机制是这样的&#xff0c; 我们滑动内部小的tableView, 开始滑动的时候&#xff0c…

C/C++ 代码注释规范及 doxygen 工具

参考 谷歌项目风格指南——注释 C doxygen 风格注释示例 ubuntu20 中 doxygen 文档生成 doxygen 官方文档 在 /Doxygen/Special Command/ 章节介绍 doxygen 的关键字 注释说明 注释的目的是提高代码的可读性与可维护性。 C 风格注释 // 单行注释/* 多行注释 */ C 风格注…

【论文阅读笔记】Meta 3D AssetGen

【论文阅读笔记】Meta 3D AssetGen: Text-to-Mesh Generation with High-Quality Geometry, Texture, and PBR Materials Info摘要引言创新点 相关工作T23D基于图片的3d 重建使用 PBR 材料的 3D 建模。 方法文本到图像:从文本中生成阴影和反照率图像Image-to-3D:基于pbr的大型重…

搭建NEMU与QEMU的DiffTest环境(动态库方式)

搭建NEMU与QEMU的DiffTest环境&#xff08;动态库方式&#xff09; 1 DiffTest原理简述2 编译NEMU3 编译qemu-dl-difftest3.1 修改NEMU/scripts/isa.mk3.2 修改NEMU/tools/qemu-dl-diff/src/diff-test.c3.3 修改NEMU/scripts/build.mk3.4 让qemu-dl-difftest带调试信息3.5 编译…

安卓的组件

人不走空 &#x1f308;个人主页&#xff1a;人不走空 &#x1f496;系列专栏&#xff1a;算法专题 ⏰诗词歌赋&#xff1a;斯是陋室&#xff0c;惟吾德馨 目录 &#x1f308;个人主页&#xff1a;人不走空 &#x1f496;系列专栏&#xff1a;算法专题 ⏰诗词歌…

【Linux】打包命令——tar

打包和压缩 虽然打包和压缩都涉及将多个文件组合成单个实体&#xff0c;但它们之间存在重要差异。 打包和压缩的区别&#xff1a; 打包是将多个文件或目录组合在一起&#xff0c;但不对其进行压缩。这意味着打包后的文件大小可能与原始文件相同或更大。此外&#xff0c;打包…

数字化精益生产系统--APS 排程管理系统

APS&#xff08;Advanced Planning and Scheduling&#xff09;排程管理系统&#xff0c;即高级生产计划与排程系统&#xff0c;是一种高度智能化的计划和排程系统。它通过整合各种生产和供应链数据&#xff0c;运用先进的算法和数据模型&#xff0c;根据各种约束条件&#xff…

MySQL篇三:数据类型

文章目录 前言1. 数值类型1.1 tinyint类型1.2 bit类型1.3 小数类型1.3.1 float1.3.2 decimal 2. 字符串类型2.1 char2.2 varchar2.3 char和varchar比较 3. 日期类型4. enum和set 前言 数据类型分类&#xff1a; 1. 数值类型 1.1 tinyint类型 在MySQL中&#xff0c;整型可以指…

【Java13】包

“包”这个机制&#xff0c;类似于分组。主要作用是区分不同组内的同名类。例如&#xff0c;高三三班有一个“王五”&#xff0c;高二八班也有一个“王五”。高三三班和高三八班就是两个不同的包。 Java中的包&#xff08;package&#xff09;机制主要提供了类的多层命名空间&…

HTTP长连接

长连接优点 HTTP为什么要开启长连接呢? 主要是为了节省建立的时间,请求可以复用同一条TCP链路,不用重复进行三握+四挥 如果没有长连接,每次请求都做三握+四挥 如果有长链接,在一个 TCP 连接中可以持续发送多份数据而不会断开连接,即请求可以复用TCP链路 长连接缺点 …