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

数据结构-8.Java. 七大排序算法(上篇)

本篇博客给大家带来的是排序的知识点, 由于时间有限, 分两天来写, 上篇主要实现 前四种排序算法: 直接插入, 希尔, 选择, 堆排。

文章专栏: Java-数据结构

若有问题 评论区见

欢迎大家点赞 评论 收藏 分享

如果你不知道分享给谁,那就分享给薯条.

你们的支持是我不断创作的动力 .

    

目录

    

  王子公主请阅

1.排序的概念及应用

1.1 排序的概念

1.3 常见的排序算法

2. 常见排序算法的实现(默认排升序)

2.1 插入排序

2.1.1基本思想:

2.1.2 直接插入排序

直接插入排序具体操作: 

2.1.3 希尔排序(缩小增量排序)

2.2 选择排序

2.2.1基本思想:

2.2.3 堆排序


  王子公主请阅

1.排序的概念及应用

1.1 排序的概念

排序:所谓排序,就是使一串记录按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作。

稳定性 :假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中,r[i]=r[j] ,且 r[i] r[j] 之前,而在排序后的序列中, r[i] 仍在 r[j] 之前,则称这种排序算法是稳定的;否则称为不稳定的。
内部排序 :数据元素全部放在内存中的排序。
外部排序 :数据元素太多不能同时放在内存中,根据排序过程的要求不能在内外存之间移动数据的排序。

1.3 常见的排序算法

2. 常见排序算法的实现(默认排升序)

2.1 插入排序

2.1.1基本思想:

直接插入排序是一种简单的插入排序法,其基本思想是:

把待排序的记录按其关键码值的大小逐个插入到一个已经排好序的有序序列中,直到所有的记录插入完为止,得到 一个新的有序序列 。实际中我们玩扑克牌时,就用了插入排序的思想。

如下模拟动图: 

2.1.2 直接插入排序

当插入第i(i>=1)个元素时,前面的array[0],array[1],…,array[i-1]已经排好序,
此时用array[i]的排序码与array[i-1],array[i-2],…的排序码顺序进行比较,找到插入位置
array[i]插入,原来位置上的元素顺序后移
如下图: 

直接插入排序具体操作: 

第一步 理清思路:

 当插入第i(i>=1)个元素时,前面的array[0],array[1],…,array[i-1]已经排好序,

此时用array[i]的排序码与array[i-1],array[i-2],…的排序码顺序进行比较,找到插入位置
array[i]插入,原来位置上的元素顺序后移
第二步具体步骤: 

1.   定义 tmp 保存 排序前 i 下标对应的值.  for(i) 为 外循环, for(j) 为  内循环 , j = i -1 .

2.   遍历数组,  在内循环中,  tmp 与  array[ j ] 进行比较,, 若是 tmp 小 则  [ j + 1] = [ j ];

若是 tmp 大 则 直接 break;  

3.    在外循环中  将 最后 j + 1 位置的值 赋为 tmp值 , [ j + 1 ] = tmp;  

第三步  画图理解 , 一目了然 :

第四步  代码实现: 

 /*** 时间复杂度:*            最好情况:数据完全有序的时候 1 2 3 4 5 :O(N)*            最坏情况:数据完全逆序的时候 5 4 3 2 1 :O(N^2)*         结论: 数据越有序,排序越快, *         场景: 现在有一组基本有序的数据,那么用哪个排序好点? - 直接插入排序.* 空间复杂度: O(1)* 稳定性:  稳定的排序*      一个本身就是稳定的排序 是可以实现为不稳定的排序的*      相反 一个本身就不稳定的排序  是不可以实现为稳定的排序的.** @param //直接插入排序*/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(array[j] > tmp) {  // >= 会变成不稳定的array[j+1] = array[j];}else {//array[j+1] = tmp; 执行了一次break;}}//当j=-1时,a[j+1]=tmp这条语句没被执行,所以再写一次array[j+1] = tmp; //执行了两次, 故把第一次屏蔽.}}

最后总结: 

1. 元素集合越接近有序,直接插入排序算法的时间效率越高
2. 时间复杂度:O(N^2)
3. 空间复杂度:O(1),它是一种稳定的排序算法
4. 稳定性:稳定 

2.1.3 希尔排序(缩小增量排序)

希尔排序本质上 就是 在对直接插入排序做优化。

第一步 了解基本思想: 

先选定一个整数 gap ,把待排序文件中所有记录分成多个组,
此处 gap 通常都是 初始化成 gap = array.length/2;
所有 距离为 gap 的记录 在同一组内,并对每一组内的记录进行直接插入排序。
每进行一次直接插入排序 gap /= 2 重复上述分组和排序的工作。当 gap =  时,所有记录在同一组内进行直接插入排序
第二步 画图辅助理解: 
第三步 具体步骤:
具体步骤与 直接插入排序的大体相同, 将 外循环条件换成for (int i = gap; i < array.length; i++),
外循环中 j = i - gap 而不是 - 1;  
同时, 内循环变成for (; j >= 0; j -= gap)
赋值条件变为array[j+gap] = tmp;
最后在直接插入排序外加一层 gap /= 2 的循环 就大功告成了.
第四步  代码实现: 
/*** 希尔排序** 时间复杂度:*        n^1.3 - n^1.5*  空间复杂度: O(1)**  稳定性: 不稳定* @param //shell*/public static void shellSort(int[] array) {int gap = array.length;while(gap > 1) {gap /= 2;shell(array,gap);}//gap /= 2;不用写   因为gap=2或3时, gap/2 = 1.已经进行了直接插入排序.}private 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 -= gap) {if(array[j] > tmp) {array[j+gap] = array[j];}else {break;}}array[j+gap] = tmp;}}

最后 希尔排序的特性总结

1. 希尔排序是对直接插入排序的优化。
2. gap > 1时都是预排序,目的是让数组更接近于有序。当gap == 1时,数组已经接近有序的了,这样就会很快。这样整体而言,可以达到优化的效果。
3. 希尔排序的时间复杂度不好计算,因为gap的取值方法很多,导致很难去计算,因此在好些树中给出的希尔排序的时间复杂度都不固定:O(n^1.25) ~ O(1.6 * n^1.25)
4. 稳定性:不稳定

2.2 选择排序

2.2.1基本思想:

每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完 。
如下模拟动图: 
第一步 理清思路:
在元素集合 array[ i ] ~ array[ n-1 ] 中选择关键码最 的数据元素
若它不是这组元素中的 第一个 元素,则将它与这组元素中的最后一个(第一个)元素交换
在剩余的 array[ i ]  ~ array[ n-2 ] array[ i+1 ]  ~  array[ n-1 ] )集合中,重复上述步骤,直到集合剩余 1 个元素
第二步 具体步骤: 
1.  写个双层循环, for( i ) 为 外层循环,  for( j ) 为外层循环, 定义minIndex =  i , j = i + 1;
2.   [minIndex] 与 [ j ] 比较, 当[minIndex] > [ j ] 时  二者交换. 
第三步  代码实现:
/*** 选择排序** 时间复杂度:*      最好: O(N^2)*      最坏: O(N^2)*空间复杂度:O(N)** 稳定性: 不稳定** @param array*/public static void selectSort(int[] array) {for (int i = 0; i < array.length-1; i++) {int minIndex = i;for (int j = i+1; j < array.length; j++) {if(array[j] < array[minIndex]) {minIndex = j;}}swap(array,minIndex,i);}}public static void swap(int[] array,int i,int j) {int tmp = array[i];array[i] = array[j];array[j] = tmp;}

选择排序有 第二种写法,  反正都要遍历一遍数组, 不如把最大值和最小值都找出来, 最小的往最前放, 最大的往最后放. 

第二种写法步骤:

 1.  定义 left = 0, right = array.length-1, i = left + 1; minIndex = maxIndex = 0;

2.   while( left < right )循环,  i 在循环中, 遍历数组 找到最小元素下标 和 最大元素下标, 出循环 与 minIndex 和 maxIndex 交换.  

3. 出循环后 考虑一个特殊情况 , 当 left = 0 下标 对应的值就是最大值时, 第二步出循环后的交换操作 将最大值交换到minIndex下标处了. 需要 再将 maxIndex 标记到最大值.

第二种写法代码实现:

public static void swap(int[] array,int i,int j) {int tmp = array[i];array[i] = array[j];array[j] = tmp;}//选择排序的第二种写法.public static void selectSort2(int[] array) {int left = 0;int right = array.length-1;while(left < right) {int minIndex = left;int maxIndex = left;for (int i = left; i <= right; i++) {if(array[i] < array[minIndex]) {minIndex = i;}if(array[i] > array[maxIndex]) {maxIndex = i;}}swap(array,left,minIndex);//有一种情况是maxIndex原本就在left位置上,上面的交换将最大值交换到minIndex下标处了.导致后续的排序不正确.if(maxIndex == left) {maxIndex = minIndex;}swap(array,right,maxIndex);left++;right--;}}

第四步 直接选择排序的特性总结:

1. 直接选择排序思考非常好理解,但是效率不是很好。实际中很少使用
2. 时间复杂度:O(N^2)
3. 空间复杂度:O(1)
4. 稳定性:不稳定

2.2.3 堆排序

堆排序 (Heapsort) 是指利用堆积树(堆)这种数据结构所设计的一种排序算法,它是选择排序的一种。它是通过堆来进行选择数据。需要注意的是排升序要建大堆,排降序建小堆。
第一步  具体步骤:
1. 排升序, 建大堆 , 向下调整算法 , parent 从 (array.length - 1)/2 开始 减到 1 
2. 将最后一个元素与首元素交换, 除末尾元素外, 其余元素调整成大根堆
3. 定义一个end = array.length - 1; while (end > 0) 循环中进行 2 步骤.
第二步  代码实现: 
 /***堆排序** 时间复杂度:O(N)+O(N*logN) 约等于 O(N*logN)** 如果都以最坏的情况来看,堆排序是目前来说最快的,希尔排序其次.* 假设希尔排序为O(N^1.3) 当N越大时,logN趋于不变所以,堆排序O(N*logN)要快一些.**  空间复杂度:O(1)*  稳定性:不稳定*/public static void heapSort(int[] array) {//建大堆createBigHeap(array);//O(N)int end = array.length-1;//O(N*logN)while(end > 0) {swap(array,0,end);shiftDown(array,0,end);end--;}}private static void createBigHeap(int[] array) {for (int parent = (array.length-1-1)/2; parent >= 0; parent--) {shiftDown(array,parent,array.length);}}private static void shiftDown(int[] array,int parent,int end) {int child = (parent*2)+1;while(child < end) {//保证右子树存在并且当右子树大的时候,child++来到右子树的下标.if(child+1 < end && array[child+1] > array[child]) {child++;}if(array[child] > array[parent]) {swap(array,child,parent);parent = child;child = parent*2+1;}else {//本身就是大根堆break;}}}

第三步   堆排序的特性总结:

1. 堆排序使用堆来选数,效率就高了很多。
2. 时间复杂度:O(N*logN)
3. 空间复杂度:O(1)
4. 稳定性:不稳定

相关文章:

数据结构-8.Java. 七大排序算法(上篇)

本篇博客给大家带来的是排序的知识点, 由于时间有限, 分两天来写, 上篇主要实现 前四种排序算法: 直接插入, 希尔, 选择, 堆排。 文章专栏: Java-数据结构 若有问题 评论区见 欢迎大家点赞 评论 收藏 分享 如果你不知道分享给谁,那就分享给薯条. 你们的支持是我不断创作的动力 …...

YOLOV5/rknn生成可执行文件部署在RK3568上

接上一篇文章best-sim.rknn模型生成好后&#xff0c;我们要将其转换成可执行文件运行在RK3568上&#xff0c;这一步需要在rknpu上进行&#xff0c;在强调一遍&#xff01;&#xff01;rknpu的作用是可以直接生成在开发板上运行的程序 退出上一步的docker环境 exit1.复制best-…...

java http body的格式 ‌application/x-www-form-urlencoded‌不支持文件上传

在Java中&#xff0c;HTTP请求的body部分可以包含多种格式的数据&#xff0c;主要包括以下几种‌&#xff1a; ‌application/x-www-form-urlencoded‌&#xff1a;这种格式将数据编码成键值对的形式&#xff0c;键和值都进行了URL编码&#xff0c;键值对之间用&符号连接。…...

GPU服务器厂家:为什么要选择 GPU 服务器?

文章来源于百家号&#xff1a;GPU服务器厂家 嘿&#xff0c;各位小伙伴们&#xff01;今天咱来聊聊为啥要选择 GPU 服务器&#xff0c;特别是定制化的那种哦。 你们知道吗&#xff1f;现在定制化 GPU 服务器那可是超火的&#xff0c;简直就是科研项目的超强 “外挂”&#x…...

Python操作neo4j库py2neo使用之py2neo 删除及事务相关操作(三)

Python操作neo4j库py2neo使用之py2neo 删除及事务相关操作&#xff08;三&#xff09; py2neo 删除 1、连接数据库 from py2neo import Graph graph Graph("bolt://xx.xx.xx.xx:7687", auth(user, pwd), nameneo4j)2、删除节点 # 删除单个节点 node graph.node…...

Idea忽略提交文件、Idea设置文件隐藏、Idea提交时隐藏部分文件、git提交时忽略文件

文章目录 一、在idea中commit文件时隐藏文件方式一&#xff1a;创建.gitignore文件&#xff08;推荐&#xff09;方式二&#xff1a;‌通过File Types设置隐藏文件方式三&#xff1a;通过Git配置忽略文件‌&#xff08;不推荐&#xff09;总结 二、可能遇到的问题2.1、.gitigno…...

python如何使用spark操作hive

文章目录 1、服务启动2、修改配置3、验证4、开发环境编写代码操作hive 1、服务启动 # 启动hdfs和yarn start-all.sh # 日志服务也需要启动一下 mapred --daemon start historyserver # 启动spark的日志服务 /opt/installs/spark/sbin/start-history-server.sh #启动hive的meta…...

观察者模式和订阅模式

观察者模式和订阅模式在概念上是相似的&#xff0c;它们都涉及到一个对象&#xff08;通常称为“主题”或“发布者”&#xff09;和多个依赖对象&#xff08;称为“观察者”或“订阅者”&#xff09;之间的关系。然而&#xff0c;尽管它们有相似之处&#xff0c;但在某些方面也…...

基于ToLua的C#和Lua内存共享方案保姆级教程

C#和Lua内存共享方案保姆级教程 前言 在介绍C#和Lua内存共享方案之前,先介绍下面两个点来支撑这个方案的必要性 跨语言交互很费 Lua和C#交互最早是基于反射的方式实现的,后来为了提升性能发展成Luajit+C#静态方法导出注入到lua虚拟机的方式至此Lua+Unity的性能才达到了实…...

OpenCV与AI深度学习|16个含源码和数据集的计算机视觉实战项目(建议收藏!)

本文来源公众号“OpenCV与AI深度学习”&#xff0c;仅用于学术分享&#xff0c;侵权删&#xff0c;干货满满。 原文链接&#xff1a;分享&#xff5c;16个含源码和数据集的计算机视觉实战项目 本文将分享16个含源码和数据集的计算机视觉实战项目。具体包括&#xff1a; 1. 人…...

Vue 如何简单更快的对 TypeScript 中接口的理解?应用场景?

TypeScript 中接口&#xff08;Interface&#xff09;的理解与应用 在 TypeScript 中&#xff0c;接口&#xff08;Interface&#xff09; 是一种用来定义对象的结构或形状的方式。接口可以指定对象中应该包含哪些属性、这些属性的类型以及它们的函数签名。接口帮助我们在代码…...

R语言绘图过程中遇到图例的图块中出现字符“a“的解决方法

R语言绘图过程中遇到图例的图块中出现字符的解决方法 因为我遇到这个问题的时候没在网上找到合适的方法&#xff0c;找到个需要付费的&#xff0c;算了。也许是因为问的方式不同&#xff0c;问了半天AI也回答出来&#xff0c;莫名有些烦躁&#xff0c;打算对代码做个分析&…...

视图合并机制解析 | OceanBase查询优化

背景 在默认配置下&#xff0c;若查询语句中嵌入了视图&#xff0c;系统会先等待视图内部所包含的查询完全执行完成后&#xff0c;再继续执行父查询。这种方式造成优化器无法将视图查询与外层查询视为一个整体来进行优化处理&#xff0c;从而限制了优化效果。因此&#xff0c;…...

sql注入报错分享(mssql+mysql)

mysql mysql的报错内容比较多 网上也有比较多的 这里重复的就不多介绍了。一笔带过 溢出类 bigint 当超过mysql的整形的时候&#xff0c;就会导致溢出&#xff0c;mysql可能会将错误信息带出。这里user()是字母默认为0 取反以后1可能就会导致异常。 报错特征 BIGINT UNSIG…...

PHP 高并发解决方案

PHP作为一种脚本语言&#xff0c;在处理高并发请求时可能面临一些挑战。但通过合理的设计和优化&#xff0c;可以有效提升PHP应用程序的性能和并发处理的能力。 一、缓存 页面缓存&#xff1a;将生成的页面缓存起来&#xff0c;减少对数据库的查询&#xff0c;提高响应速度。…...

k8s1.30.0高可用集群部署

负载均衡 nginx负载均衡 两台nginx负载均衡 vim /etc/nginx/nginx.conf stream {upstream kube-apiserver {server 192.168.0.11:6443 max_fails3 fail_timeout30s;#server 192.168.0.12:6443 max_fails3 fail_timeout30s;#server 192.168.0.13:6443 max_fails3…...

多摩川编码器协议及单片机使用

参考&#xff1a; https://blog.csdn.net/qq_28149763/article/details/132718177 https://mp.weixin.qq.com/s/H4XoR1LZSMH6AxsjZuOw6g 1、多摩川编码器协议 多摩川数据通讯是基于485 硬件接口标准NRZ 协议&#xff0c;通讯波特率为2.5Mbps 的串行通讯&#xff0c;采用差分两…...

Android 网络通信(三)OkHttp实现登入

学习笔记 目录 一. 先写XML布局 二、创建 LoginResponse 类 :封装响应数据 目的和作用: 三、创建 MyOkHttp 类 :发送异步请求 代码分析 可能改进的地方 总结 四、LoginActivity 类中实现登录功能 详细分析与注释: 总结: 改进建议: 零、响应数据样例 通过 P…...

分享一下arr的意义(c基础)(必看)(牢记)

arr 即数组名 一般指数组首元素地址 在两种情况下不是 1&#xff1a;sizeof&#xff08;arr&#xff09; arr指整个数组简单讲解一下strlen与sizeof&#xff08;c基础&#xff09;_strzeof在c语言中什么意思-CSDN博客 2&#xff1a;printf&#xff08;"%p",&…...

AGENT AI 综述核心速览

研究背景 研究问题&#xff1a;这篇文章探讨了多模态人工智能&#xff08;Agent AI&#xff09;系统在理解和响应视觉和语言输入方面的潜力&#xff0c;特别是在物理和虚拟环境中的应用。Agent AI旨在通过感知和行动来增强人工智能系统的交互性和适应性。研究难点&#xff1a;…...

基于Java Springboot房屋租赁系统

一、作品包含 源码数据库设计文档万字PPT全套环境和工具资源部署教程 二、项目技术 前端技术&#xff1a;Html、Css、Js、Vue、Element-ui 数据库&#xff1a;MySQL 后端技术&#xff1a;Java、Spring Boot、MyBatis 三、运行环境 开发工具&#xff1a;IDEA/eclipse 数据…...

力扣 LeetCode 701. 二叉搜索树中的插入操作(Day10:二叉树)

解题思路&#xff1a; 全部插入到叶子节点即可 class Solution {public TreeNode insertIntoBST(TreeNode root, int val) {if (root null) {TreeNode node new TreeNode(val);return node;}if (root.val < val) {root.right insertIntoBST(root.right, val);}if (root…...

猎板科技:PCB 特殊定制领域的卓越引领者

一、专业团队&#xff0c;创新设计之源 猎板科技的核心竞争力首先源于其卓越的专业团队。这支队伍汇聚了经验丰富的资深工程师以及行业前沿的技术专家&#xff0c;他们在 PCB 设计领域拥有深厚的造诣和敏锐的洞察力。无论是面对常规 PCB 设计任务&#xff0c;还是应对极具挑战…...

centos stream 9安装docker教程

第一步&#xff1a;安装该dnf-plugins-core软件包&#xff08;它提供了管理 DNF 存储库的命令&#xff09; sudo dnf -y install dnf-plugins-core 第二步&#xff1a;设置存储库(这里使用的是阿里云的镜像源) sudo dnf config-manager --add-repo https://mirrors.aliyun.c…...

优化旧LabVIEW程序功能的方法

优化运行已久的LabVIEW程序时&#xff0c;需在不影响原有功能的基础上针对目标功能进行改进。以下结合一个数据采集功能优化的实例&#xff0c;详细说明操作步骤和注意事项&#xff0c;为工程师提供切实可行的方法。 优化背景 某企业的LabVIEW程序负责多通道数据采集&#xf…...

关于安卓模拟器或手机设置了BurpSuite代理和安装证书后仍然抓取不到APP数据包的解决办法

免责申明 本文仅是用于学习研究安卓系统设置代理后抓取不到App数据包实验,请勿用在非法途径上,若将其用于非法目的,所造成的一切后果由您自行承担,产生的一切风险和后果与笔者无关;本文开始前请认真详细学习《‌中华人民共和国网络安全法》【学法时习之丨网络安全在身边一…...

【电路笔记】-布尔逻辑AND函数

逻辑AND函数 文章目录 逻辑AND函数1、概述2、逻辑 AND 函数 仅当所有输入均为 true 时&#xff0c;逻辑与函数输出才为 true&#xff0c;否则输出为 false。 1、概述 布尔代数基于逻辑函数&#xff0c;其中每个布尔函数&#xff08;例如逻辑 AND 函数&#xff09;通常具有一个…...

C#(11) 运算符重载

前言 我们知道函数是可以重载的&#xff0c;重载后的作用是干嘛呢&#xff1f;其实就是为了方便适应不同的参数传递。 那运算符我们也可以理解是一个函数&#xff0c;只是我们希望为更多的参数引入运算符使得他们可以被计算。 c#设计这么一块功能&#xff0c;其实也是为了方…...

Linux下Intel编译器oneAPI安装和链接MKL库编译

参考: https://blog.csdn.net/qq_44263574/article/details/123582481 官网下载: https://www.intel.com/content/www/us/en/developer/tools/oneapi/base-toolkit-download.html?packagesoneapi-toolkit&oneapi-toolkit-oslinux&oneapi-linoffline 填写邮件和国家,…...

【通俗理解】ELBO(证据下界)——机器学习中的“情感纽带”

【通俗理解】ELBO&#xff08;证据下界&#xff09;——机器学习中的“情感纽带” 关键词提炼 #ELBO #证据下界 #变分推断 #机器学习 #潜变量模型 #KL散度 #期望 #对数似然 第一节&#xff1a;ELBO的类比与核心概念【尽可能通俗】 ELBO&#xff0c;即证据下界&#xff0c;在…...