数据结构与算法:基于比较的排序算法:选择、冒泡、插入、归并的动图演示和java代码,排序时间复杂度、空间复杂度、稳定性总结表格

news2024/11/19 9:27:26

选择排序

选择排序是先在0~N-1上选择一个最小值排到最前面,然后再在1到N-1上选一个次小的,以此类推。
在这里插入图片描述

public static selectionSort(int[] arr){
	if(arr==null||arr.length<2){
		return;
	}
//每次从i n-1 选一个最小的放前面
	for(int i=0;i<=arr.length-2;i++){
		int minIdx = i;
		for(int j=i+1;j<=arr.length-1;j++){
			if(arr[minIdx]>arr[j]) minIdx=j;
		}
		swap(arr,i,minIdx);
	}
}

public static void swap(int[] arr,int i,int j){
	if(i==j) return;
	arr[i]=arr[i]^arr[j];
	arr[j]=arr[i]^arr[j];
	arr[i]=arr[i]^arr[j];
}

冒泡排序

在这里插入图片描述

public static selectionSort(int[] arr){
	if(arr==null||arr.length<2){
		return;
	}
//每次遍历0 i
	for(int i=arr.length-1;i>=1;i--){
		for(int j=0;j<i;j++){
			if(arr[j+1]>arr[j]) swap(arr,j,j+1);
		}
	}
}

public static void swap(int[] arr,int i,int j){
	if(i==j) return;
	arr[i]=arr[i]^arr[j];
	arr[j]=arr[i]^arr[j];
	arr[i]=arr[i]^arr[j];
}

插入排序

插入排序是先让0到1变得有序,然后让0到2变得有序,以此类推。
在这里插入图片描述

public static void insertionSort(int[] arr){
	if(arr==null||arr.length<2){
		return;
	}
	//0~0 已经有序
	//0~i 想变有序
	for(int i=1;i<arr.length;i++){
		for(int j=i-1;j>=0&&arr[j]>arr[j+1];j--){
			swap(arr,j,j+1);
		}
	}
}

public static void swap(int[] arr, int i, int j){
	if(i==j) return;
	arr[i]=arr[i]^arr[j];
	arr[j]=arr[i]^arr[j];
	arr[i]=arr[i]^arr[j];
}

归并排序

在这里插入图片描述

public static void mergeSort(int[] arr){
	process(arr,0,arr.length-1);
}

public static void process(int[] arr,int L,int R){
	if(L==R) return;
	int mid=L+(R-L)>>1;
	process(arr,L,mid);
	process(arr,mid+1,R);
	merge(arr,L,mid,R);
}
public static void merge(int[] arr,int L,int mid,int R){
	int[] temp=new int[R-L+1];
	int i=0;
	int p1=L;
	int p2=R;
	while(p1<=mid&&p2<=R){
		if(arr[p1]<arr[p2]) temp[i++]=arr[p1++];
		else temp[i++]=arr[p2++];
	}
	while(p1<=mid) temp[i++]=arr[p1++];
	while(p2<=R) temp[i++]=arr[p2++];
	for(i=0;i<temp.length;i++){
		arr[L+i]=temp[i++];
	}
}

时间复杂度,用Master主定理算出来是O(N*logN),空间复杂度为O(N)

稳定性

定义

一个排序算法具有稳定性的意思是在排序相同值数据的前后,数据之间的相对顺序不变。
譬如我现在有一个待排序列:3 3 1
那么前两个3是值相等的,我们现在给这个待排序列打上标记:3① 3② 1
排完序后这个序列依旧是3①在3②的左边,那么我们就称这个排序算法具有稳定性。

应用场景

要求稳定性的场景一般是多条件排序,我们需要保留前几轮排序的相对顺序。
譬如一个商品排行榜的比较标准为:质量分高的在前,质量分相同的话看价格,价格低对的在前。这时候我们就需要具有稳定性的算法,因为相当于有两轮条件比较,质量分和价格。我们在比较价格时需要保证质量分排序的相对顺序不变。
体现在数据结构中就是,一般自定义的,复杂的数据结构才需要稳定性的存在。

基于比较的排序对比总结

目前在基于比较的排序算法中,没有找到时间复杂度为O(N*logN) ,空间复杂度为O(1),又稳定的排序。

面试版

以下稳定性为√的意思是该算法可以实现成稳定性的,要看具体的实现逻辑。
但是为×的就是一般情况下该算法是无法实现成稳定性的(但如果)。
且快排是基于随机数实现的快排。

算法时间复杂度空间复杂度稳定性
选择O(N^2)O(1)×
冒泡O(N^2)O(1)
插入O(N^2)O(1)
归并O(N*logN)O(N)
快排O(N*logN)O(logN)×
O(N*logN)O(1)×

各个排序算法关于稳定性的细节

一般只要是跨多个值交换位置的算法,就会丧失稳定性。

选择排序

选择排序是先在0~N-1上选择一个最小值排到最前面,然后再在1到N-1上选一个次小的,以此类推。
这种跨多个值交换位置的,很明显没有稳定性。譬如序列:3① 3② 1 3③
最终会变为:1 3② 3① 3③

冒泡排序

因为是相邻位置交换,所以具有稳定性

插入排序

插入排序是先让0到1变得有序,然后让0到2变得有序,以此类推。
那么我们只需要在遍历当前数并往前比较时,碰到一样的不交换,即可保证稳定性。

归并排序

归并排序是先让小区间变得有序,然后合并成大区间。
我们只需要在合并时,左右区间是相等的数,先取左那么就可保证稳定性。

快速排序

快速排序的两个版本,第一个版本是,通过选择一个基准值,将数组分割成两个区,一个区小于等于基准值,一个区大于基准值。然后递归地对两区进行快速排序。
第二个版本是,通过选择一个基准值,将数组分割成三个区,一个区小于基准值,一个区等于基准值,一个区大于基准值。然后递归地对三区进行快速排序。

如果是第一个版本,当遍历到小于等于基准值的数时,就要和小于等于区的下一个数做交换。这一般也是跨多个值进行交换的,所以没有稳定性。
如果是第二个版本,当遍历到小于基准值的数时,就要和小于区的下一个数做交换。这一般也是跨多个值进行交换的,所以没有稳定性。

堆排序

堆排序更不用说,从始至终所有步骤都不能保证稳定性。

详细版

在这里插入图片描述

排序算法的优化

归并算法可以利用内部缓存法将空间复杂度优化为O(1),但是代码实现过于复杂,不建议掌握。
同时“原地归并排序”也可以将空间复杂度优化为O(1),但是时间复杂度就变为O(N^2)了。
快速排序可以实现稳定性,但是代码实现过于复杂,不建议掌握。
总而言之,不用去考虑太多这些主流版本之外的优化版本。

工程上对于排序算法的改进

在项目或者工程中一般会考虑以下两点:1、样本量小和大。2、是否需要稳定性
譬如样本量小时,时间复杂度上O(N^2)和O(N*logN)区别不大,但O(N平方)算法的空间复杂度几乎都为O(1),所以小样本其实应该用选择排序、冒泡排序、插入排序等算法。

同时,

本篇文章看不懂的可以去看视频,因为本篇文章是基于此视频做的总结和扩充笔记:https://www.bilibili.com/video/BV13g41157hK?p=6

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

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

相关文章

深入Apache Commons Config:管理和使用配置文件

第1章&#xff1a;引言 咱们都知道&#xff0c;在软件开发中&#xff0c;管理配置文件是一件既重要又让人头疼的事。想象一下&#xff0c;咱们的应用程序有一堆设置需要调整&#xff0c;比如数据库的连接信息、应用的端口号&#xff0c;或者是一些功能的开关。如果这些信息硬编…

Spring高手之路-SpringBean的生命周期

目录 SpringBean的生命周期 整体介绍 详细介绍 1.实例化Bean 2.设置属性值 3.检查Aware 4.调用BeanPostProcessor的前置处理方法 5.调用InitializingBean的afterPropertiesSet方法 6.调用自定义init-method方法 7.调用BeanPostProcessor的后置处理方法 8.注册Destru…

【深入之Java进阶篇】fastjson的反序列化漏洞(详解总结)

✔️ fastjson的反序列化漏 1️⃣典型解析2️⃣拓展知识仓1️⃣AutoType2️⃣AutoType 有何错?3️⃣ 绕过checkAutotype&#xff0c;黑客与fastjson的博弈4️⃣autoType不开启也能被攻击?5️⃣利用异常进行攻击6️⃣AutoType 安全模式? 1️⃣典型解析 当我们使用fastjson进行…

ueditor富文本编辑器中图片上传地址配置以及抓取远程图片地址的配置

一&#xff1a;图片上传保存地址配置 打开文件ueditor.php,找到imagePathFormat进行修改即可 一&#xff1a;远程抓取图片配置 打开文件ueditor.config.js,找到catchRemoteImageEnable&#xff0c;取消注释即可

Unity之ShaderGraph如何实现瓶装水效果

前言 有一个场景在做效果时,有一个水瓶放到桌子上的设定,但是模型只做了个水瓶,里面是空的,所以我就想办法,如何做出来瓶中装睡的效果,最好是能跟随瓶子有液体流动的效果。 如下图所示: 水面实现 水面效果 液体颜色设置 因为液体有边缘颜色和内里面颜色,所以要分开…

strlen和sizeof的初步理解

大家好我是Beilef&#xff0c;一个美好的下我接触到编程并且逐渐喜欢。我虽然不是科班出身但是我会更加努力地去学&#xff0c;有啥不对的地方请斧正 文章目录 目录 文章目录 前言 想必大家对sizeof肯定很了解&#xff0c;那对strlen又了解多少。其实这个问题应该让不少人困扰。…

内网穿透的应用-Ubuntu安装XRDP远程桌面结合内网穿透实现远程桌面Ubuntu

文章目录 一、 同个局域网内远程桌面Ubuntu二、使用Windows远程桌面连接三、公网环境系统远程桌面Ubuntu1. 注册cpolar账号并安装2. 创建隧道&#xff0c;映射3389端口3. Windows远程桌面Ubuntu 四、 配置固定公网地址远程Ubuntu1. 保留固定TCP地址2. 配置固定的TCP地址3. 使用…

python 通过opencv及face_recognition识别人脸

效果&#xff1a; 使用Python的cv2库和face_recognition库来进行人脸检测和比对的 0是代表一样 认为是同一人。 代码&#xff1a; pip install opencv-python pip install face_recognition# 导入cv2库&#xff0c;用于图像处理 import cv2 # 导入face_recognition库&#…

【MySQL】数据库之事务

目录 一、什么是事务 二、事务的ACID是什么&#xff1f; 三、有哪些典型的不一致性问题&#xff1f; 第一种&#xff1a;脏读 第二种&#xff1a;不可重复读 第三种&#xff1a;幻读 第四种&#xff1a;丢失更新 四、隔离级别有哪些&#xff1f; &#xff08;1&#xf…

Sublime Text 4 中文汉化教程(Version: Build 4169)

Sublime Text 4汉化 1 知识小课堂1.1 sublim简介1.2 其他编辑器 2 安装过程2.1 安装Install Package Control2.2 Install Package2.3 安装工具包2.4 常用的插件2.5 安装中文包 1 知识小课堂 1.1 sublim简介 Sublime是一款代码编辑器&#xff0c;致力于为开发人员提供快速、高…

IDEA 控制台中文出现乱码问题解决

一、问题概述 请看下图 二、问题分析 IDEA控制台输出乱码一般会有三种来源&#xff1a; ① IDEA本身编码错误 ② Tomcat日志输出编码错误 ③ 项目本身原因。 终极原因&#xff1a;IDEA编码和Tomcat编码不一致&#xff0c;统一设置为UTF-8即可。 三、解决思路 修改…

双向循环链表实现C语言关键字中英翻译机 ฅ( ̳• · • ̳ฅ)

目录 1.双向循环链表的声明与定义&#xff1a; 2. 创建链表并对节点中的数据赋初值 3. 插入节点并链接 4.中英翻译 5. 小游戏的实现 6.菜单的实现 7. 释放内存 8.在主函数中用刚才定义的函数实现各种代码 输入样例&#xff1a; 实现方法&#xff1a;双向循环链表来实…

同城配送小程序解决方案

前言 同城配送小程序解决方案。 一、用户用车 用户打开小程序后发货地址自动定位到用户当前位置&#xff0c;用户可通过地址后的>号在地图上选择新的发货地址和卸货地址&#xff0c;小程序会自动规划出行线路&#xff0c;计算距离和运费价格。 用户仅用简单操作后就可以…

【网络协议】远程登录安全连接协议SSH(Secure Shell)

文章目录 什么是SSH协议&#xff1f;SSH为何是安全的&#xff1f;SSH由哪些组件构成&#xff1f;SSH可以帮助实现的功能SSH的工作原理SSH的历史版本常用的SSH工具有哪些SSH配置案例参考Windows 安装SSHUbuntu系统SSH配置Cisco Switch SSH配置华为Switch SSH配置 客户端启用SSH连…

uni-app 命令行创建

1. 首先创建项目&#xff0c;命令如下: npx degit dcloudio/uni-preset-vue#vite-ts uni-app-demo如果出现报错&#xff0c;如下图. 大概率就是没有目录C:\Users\Administrator\AppData\Roaming\npm 解决办法&#xff1a; 创建目录 C:\Users\Administrator\AppData\Roaming\n…

cpp_05_类_string类

1 类的定义 1.1 构造函数 定义&#xff1a;函数名必须与类名相同&#xff0c;且没有返回值类型 &#xff0c;连void也没有。 构造函数调用时间&#xff1a; 在定义对象的同时自动被调用&#xff0c;而且仅被调用一次&#xff1a; 1&#xff09;对象定义语句 2&#xff09;n…

20231226在Firefly的AIO-3399J开发板上在Android11下调通后摄像头ov13850

20231226在Firefly的AIO-3399J开发板上在Android11下调通后摄像头ov13850 2023/12/26 8:22 开发板&#xff1a;Firefly的AIO-3399J【RK3399】 SDK&#xff1a;rk3399-android-11-r20211216.tar.xz【Android11】 Android11.0.tar.bz2.aa【ToyBrick】 Android11.0.tar.bz2.ab And…

基于多反应堆的高并发服务器【C/C++/Reactor】(中)EventLoop初始化

这个Dispatcher是一个事件分发模型&#xff0c;通过这个模型,就能够检测对应的文件描述符的事件的时候,可以使用epoll/poll/select,前面说过三选一。另外不管是哪一个底层的检测模型,它们都需要使用一个数据块,这个数据块就叫做DispatcherData。除此之外,还有另外一个部分,因为…

idea导入spring-framework异常:error: cannot find symbol

从github上clone代码spring-framework到本地后导入idea&#xff0c;点击gradle构建后控制台提示异常&#xff1a; 具体异常信息&#xff1a; /Users/ZengJun/Desktop/spring-framework/buildSrc/src/main/java/org/springframework/build/KotlinConventions.java:44: error:…

智能优化算法应用:基于侏儒猫鼬算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于侏儒猫鼬算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于侏儒猫鼬算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.侏儒猫鼬算法4.实验参数设定5.算法结果6.…