冒泡排序及其优化

news/2024/5/18 23:57:32/文章来源:https://blog.csdn.net/weixin_59216829/article/details/132806475

前言

本文将简单介绍冒泡排序及其优化版本,默认从小到大顺序

什么是冒泡排序

冒泡排序是一种简单且经典的排序算法。
基本思想: 是通过反复交换相邻的未按顺序排列的元素,将最小(或最大)的元素逐渐“浮”到正确位置。
时间复杂度: O(n^2)
排序稳定性: 稳定

说大白话就是两个位置判断是否符合小到大(大到小)顺序,不符合则交换,符合则下一轮,图例(一轮):
在这里插入图片描述

就上图所示,我们的数组{4,2,7,1,5},在交换排序这个过程中,需要两个指针进行辅助排序,两个指针是同时移动的,每移动一位就比较一次,这样就能将大的值往后放,小的值往前放,这样一轮下来,大的数是一定在被排序到数组往后位置的

既然一轮只能对部分数据进行排序,那么我们只需要多重复几次操作就可以了,次数 = arr.length - 1(2个数排序最多比较只需要1次,3个数排序最多比较需要2次)

public class BubbleSorted {public static void main(String[] args) {int[] arr = new int[]{4,2,7,1,5};for(int i = 0; i < arr.length-1; i++){for(int j = 0; j < arr.length - 1; j++){if(arr[j] > arr[j+1]){swap(arr, j, j+1);}}}for (int i : arr) {System.out.println(i+" ");}}private static void swap(int[] arr, int i, int j) {arr[i] = arr[i] ^ arr[j];arr[j] = arr[i] ^ arr[j];arr[i] = arr[i] ^ arr[j];}
}

优化一

对于上面的这种冒泡排序每两两进行比较不管是否需要,这是一种比较耗时的操作,我们通过代码举个例子:

public class BubbleSorted {public static void main(String[] args) {int[] arr = new int[]{5, 8, 6, 1, 12, 13, 14};for (int i = 0; i < arr.length - 1; i++) {for (int j = 0; j < arr.length  - 1; j++) {if (arr[j] > arr[j + 1]) {swap(arr, j, j + 1);}}System.out.println("第"+(i+1)+"次排序结果:"+Arrays.toString(arr));}}private static void swap(int[] arr, int i, int j) {arr[i] = arr[i] ^ arr[j];arr[j] = arr[i] ^ arr[j];arr[i] = arr[i] ^ arr[j];}
}

运行结果:

第1次排序结果:[5, 6, 1, 8, 12, 13, 14]
第2次排序结果:[5, 1, 6, 8, 12, 13, 14]
第3次排序结果:[1, 5, 6, 8, 12, 13, 14]
第4次排序结果:[1, 5, 6, 8, 12, 13, 14]
第5次排序结果:[1, 5, 6, 8, 12, 13, 14]
第6次排序结果:[1, 5, 6, 8, 12, 13, 14]

我们不难发现,其实后面的456次排序是压根不需要了,因为它原本就是有序的,多余的判断是浪费时间的,那么我们要如何去判断后续已经有序不需要比较呢???

很简单,假如我们在一轮比较中,都没有需要进行交换,那么就意味着后面的顺序都是有序的,也就是说,我们第5次的排序结果可以通过第4次结果推导,如果有序则不再进行剩下的几轮排序,直接break,所以我们设置一个标记位即可,下面代码示例:

public class BubbleSorted {public static void main(String[] args) {int[] arr = new int[]{5, 8, 6, 1, 12, 13, 14};for (int i = 0; i < arr.length - 1; i++) {// 没一轮排序重置标记位,只有进入交换才说明本轮的排序结果可能任然是无序的,//一次交换都没有进行,说明这一轮排序没有一个位置需要比较交换boolean flag = true;for (int j = 0; j < arr.length - 1; j++) {if (arr[j] > arr[j + 1]) {flag = false;swap(arr, j, j + 1);}}System.out.println("第"+(i+1)+"次排序结果:"+Arrays.toString(arr));if(flag){break;}}}private static void swap(int[] arr, int i, int j) {arr[i] = arr[i] ^ arr[j];arr[j] = arr[i] ^ arr[j];arr[i] = arr[i] ^ arr[j];}
}

运行结果:

第1次排序结果:[5, 6, 1, 8, 12, 13, 14]
第2次排序结果:[5, 1, 6, 8, 12, 13, 14]
第3次排序结果:[1, 5, 6, 8, 12, 13, 14]
第4次排序结果:[1, 5, 6, 8, 12, 13, 14]

我们可以发现56轮已经不用再进行了,但是我们还需要第4轮来进行排序判断。

优化二

在优化一后,我们还可以对冒泡排序进行优化

首先,我们可以观察实例的结果,不难发现,每经过一轮排序,数组倒数位置上的数一定是有序的,因为每一轮的比较,大的数一定是往后跑的,那么就意味着,我们之后的比较排序不需要在对他们进行关注,所以我们每排序一次,内循环就少判断一位,以下是代码示例:

public static void main(String[] args) {int[] arr = new int[]{5, 8, 6, 1, 12, 13, 14};for (int i = 0; i < arr.length - 1; i++) {boolean flag = true;// 内循环循环次数每次  -i  for (int j = 0; j < arr.length - i - 1; j++) {if (arr[j] > arr[j + 1]) {flag = false;swap(arr, j, j + 1);}}System.out.println("第"+(i+1)+"次排序结果:"+Arrays.toString(arr));if(flag){break;}}}private static void swap(int[] arr, int i, int j) {arr[i] = arr[i] ^ arr[j];arr[j] = arr[i] ^ arr[j];arr[i] = arr[i] ^ arr[j];}

总结

冒泡排序是一种通过相邻两个数进行比较来进行排序的,可以通过两种优化的结合尽可能的提升效率,但是当数据量大的时候,效率依旧堪忧

以上是本文全部内容,感谢阅读

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

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

相关文章

sheetjs實現頁面的數據導出execl

概述 需要給頁面的table做一個數據導出功能,發現一個好用sheetjs工具 只需要簡單的js語法如下,就可以將table的數據導出來 function load(){var date new Date();date.setTime(date.getTime() (8 * 60 * 60 * 1000));var table document.getElementById("tab");v…

Linux MyFile

在之前&#xff0c;我们应该都多少接触过了C语言的文件管理&#xff0c;fopen&#xff0c;fclose&#xff0c;fputs....等函数的用法&#xff0c;也分析了系统层面上C语言是如何实现文件管理的。 回顾 上一个文章&#xff0c;我们讲解了十分重要的知识&#xff0c;在文件被打…

故障注入实验:了解如何使用Chaos Engineering的方法,在服务网格中进行故障注入实验

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to New World.✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &a…

输入框自动保留2位小数

<template><div class"box"><el-form :model"form" :rules"rules" ref"form" label-width"120px"><el-form-item label"保留2位小数" prop"aaa"><!-- v-numberInt自定义的指…

Linux学习-Redis主从和哨兵

主从复制 一主一从结构 # 配置host61为主服务器 [roothost61 ~]# yum -y install redis [roothost61 ~]# vim /etc/redis.conf bind 192.168.88.61 #设置服务使用的Ip地址 port 6379 #设置服务使用的端口号 使用默认端口即可 [roothost61 ~]# systemctl start redis [rooth…

三、开发工具

开发工具 开发工具1.1.熟悉IDEA1.2.下载IDEA1.3.IDEA中文插件1.4.IDEA输出中文乱码1.5.使用IDEA —————————————————————————————————————————————————— —————————————————————————————————…

国内低代码开发平台有哪些?低代码真的好用吗?

“低代码”这一概念在近几年异常火爆&#xff0c;也吸引了国内大厂纷纷加入&#xff0c;像腾讯、阿里、华为、网易、百度等科技巨头都自研了自己的低代码产品&#xff0c;并同时在该领域投资了不少厂商。就比如阿里&#xff0c;其先是在2018年投资了一家低代码平台&#xff0c;…

C语言指针,深度长文全面讲解

指针对于C来说太重要。然而&#xff0c;想要全面理解指针&#xff0c;除了要对C语言有熟练的掌握外&#xff0c;还要有计算机硬件以及操作系统等方方面面的基本知识。所以本文尽可能的通过一篇文章完全讲解指针。 为什么需要指针&#xff1f; 指针解决了一些编程中基本的问题。…

嵌入式和 Java 走哪条路?

今日话题&#xff0c;嵌入式和 Java 走哪条路?嵌入式对软件感兴趣&#xff0c;走java嵌入式行业薪资并不算低&#xff0c;比上不足&#xff0c;比下有余。特别是从2020年开始&#xff0c;嵌入式也借上了芯片行业的东风火了起来。能拿多少薪资&#xff0c;受多方面因素影响。下…

激光焊接汽车PP塑料配件透光率测试仪

随着汽车主机厂对车辆轻量化的需求越来越强烈&#xff0c;汽车零部件轻量化设计、制造也成为汽车零部件生产厂商的重要技术指标。零部件企业要实现产品的轻量化&#xff0c;在材料指定的情况下&#xff0c;要通过产品设计优化、产品壁厚减小和装配方式的优化来解决。使用PP材料…

服务网格的面临挑战:探讨服务网格实施中可能遇到的问题和解决方案

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to New World.✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &a…

【案例教学】华为云API图引擎服务 GES的便捷性—AI帮助快速处理图片小助手

云服务、API、SDK&#xff0c;调试&#xff0c;查看&#xff0c;我都行 阅读短文您可以学习到&#xff1a;人工智能AI快速处理图片 1 IntelliJ IDEA 之API插件介绍 API插件支持 VS Code IDE、IntelliJ IDEA等平台、以及华为云自研 CodeArts IDE&#xff0c;基于华为云服务提供…

Java8 Stream 数据流,大数据量下的性能效率

Stream 是 Java SE 8 类库中新增的关键抽象&#xff0c;它被定义于 java.util.stream &#xff08;这个包里有若干流类型&#xff1a; Stream<T> 代表对象引用流&#xff0c;此外还有一系列特化流&#xff0c;如 IntStream&#xff0c;LongStream&#xff0c;DoubleStrea…

动画制作如何选择动作捕捉动画制作服务

近日&#xff0c;长宁ART PARK 大融城迎来了首位虚拟代言人“光艺”&#xff0c;拥有着极具感染力的笑容、数字人形象辨识度极高&#xff0c;在裸眼3D巨屏中&#xff0c;为市民带来虚实交互体验。而这种数字人动画的背后&#xff0c;大多以动作捕捉动画制作技术为主。 *素材源于…

LeetCode算法动态规划—剑指 Offer 10- II. 青蛙跳台阶问题

目录 剑指 Offer 10- II. 青蛙跳台阶问题 题解&#xff1a; 代码&#xff1a; 运行结果&#xff1a;​编辑 一只青蛙一次可以跳上1级台阶&#xff0c;也可以跳上2级台阶。求该青蛙跳上一个 n 级的台阶总共有多少种跳法。 答案需要取模 1e97&#xff08;1000000007&#xff…

MATLAB APP纯小白入门 两数相加

万事开头难&#xff0c;最怕第一次。使用matlab APP 实现两数求和&#xff0c;如下图所示&#xff0c;c a b&#xff0c;输入数字后&#xff0c;按 “” 就计算。 步骤 拖拽三个 Edit Field(Numeric) 过来&#xff0c;并且双击名字分别改为 a,b,c。注意修改名字后右边会有点变…

Python日志处理器,同时打印到控制台和保存到文件中,并保证格式一致

使用logging模块的时候&#xff0c;默认是输出到控制台的&#xff0c;当然也可以配置输出到文件中&#xff0c;但是当你配置了文件后&#xff0c;控制台的输出就消失了&#xff0c;所以&#xff0c;需要一个策略即能保存到文件中&#xff0c;又能输出到控制台中。 下面是我做的…

【计算机毕业设计】基于SpringBoot+Vue的流浪猫狗救助救援网站的设计与实现

博主主页&#xff1a;一季春秋博主简介&#xff1a;专注Java技术领域和毕业设计项目实战、Java、微信小程序、安卓等技术开发&#xff0c;远程调试部署、代码讲解、文档指导、ppt制作等技术指导。主要内容&#xff1a;毕业设计(Java项目、小程序等)、简历模板、学习资料、面试题…

求链表的倒数第k个节点

思路&#xff1a;利用快慢指针空间差 代码&#xff1a; struct ListNode* FindKthToTail(struct ListNode* pListHead, int k ) {// write code herestruct ListNode* slow pListHead;struct ListNode* fast pListHead;while(k--){if(fastNULL){return NULL;}fastfast->…

linux常用命令(4):mkdir命令(创建目录)

文章目录 一、命令简介二、命令格式三、常用示例 一、命令简介 mkdir&#xff08;make directories&#xff09;创建目录。 若指定目录不存在则创建目录。若指定目录已存在&#xff0c;则会提示已存在而不继续创建。 touch与mkdir的区别? 很多人可能会把这个搞混淆&#xff…