数据结构与算法-排序算法1-冒泡排序

本文先介绍排序算法,然后具体写冒泡排序。

目录

1.排序算法简介

2.常见的排序算法分类如下图:

3.冒泡排序:

1.介绍:

2.动态图解

3.举例

4.小结冒泡排序规则

5.冒泡排序代码

6.优化

7.优化后时间

代码:

运行结果:


1.排序算法简介

排序也称为排序算法。排序是将一组数据依据指定的顺序进行排列的过程。

分类:

  1. 内部排序:将需要处理的所有数据都加载到内存中进行排序。
  2. 外部排序:数据量过大(比如10亿个数据),无法全部加载到内存中,就需要借助外部存储(文件、磁盘等)进行排序。先加载一部分,排序完之后再加载另外一部分进行排序,排序完再合并。

2.常见的排序算法分类如下图:

稳定性口诀:

选泡插,快归堆希桶计基,不稳稳稳不稳稳,不稳不稳稳稳稳

3.冒泡排序:

1.介绍:

数组中n个元素,从数组第一个元素开始到最后一个元素,依次比较相邻元素的值,如果如果左端元素大于右端元素就交换它们的位置,使得较大的元素在右边。这样数组最右端的元素就是数组中的最大元素。一轮之后就找到了n个元素中的最大元素,浮到整个数组最后一个位置。接着对左边n-1个元素也这样交换,找到这n-1个元素中的最大值,浮到整个数组的倒数第二个位置。依此类推。直到整个数组有序排列。

冒泡排序就是用相邻交换的方式把大的元素换到右边。

2.动态图解

3.举例

比如原始数组为:3,9,-1,10,20

第一趟排序:

(1)3,9,-1,10,20将3和9比较,不用交换

(2)3,-1,9,10,20将9和-1比较,要交换

(3)3,-1,9,10,20将9和10比较,不用交换

(4)3,-1,9,10,20将10和20比较,不用交换

第二趟排序:

(1)-1,3,9,10,20将3和-1比较,要交换

(2)-1,3,9,10,20将3和9比较,不用交换

(3)-1,3,9,1020将9和10比较,不用交换

第三趟排序:

(1)-1,3,9,1020将-1和3比较,不用交换

(2)-1,3,9,10,20将3和9比较,不用交换

第四趟排序:

(1)-1,3,9,10,20将-1和3比较,不用交换

由于5个数据中四个数据已经确定顺序,所以不需要第五趟排序。

4.小结冒泡排序规则

①数组元素个数为n,就一共进行n-1次大循环

②每一趟排序的次数逐渐减少

③如果我们发现在某趟排序中没有发生一次交换,可以提前结束冒泡排序,也就是冒泡排序的优化。

5.冒泡排序代码

package com.xjj.sort;import java.util.Arrays;public class BubbleSort {public static void main(String[] args) {int arr[]={3,9,-1,10,20};BubbleSort(arr);}//为了例子写的原始写法,用于找规律public static void BubbleSort1(int []arr){int temp=0;//第一趟排序for(int j=0;j<arr.length-1;j++){if(arr[j]>arr[j+1]){temp=arr[j];arr[j]=arr[j+1];arr[j+1]=temp;}}System.out.println("第1趟排序后的结果:"+Arrays.toString(arr));//第二趟排序for(int j=0;j<arr.length-1-1;j++){if(arr[j]>arr[j+1]){temp=arr[j];arr[j]=arr[j+1];arr[j+1]=temp;}}System.out.println("第2趟排序后的结果:"+Arrays.toString(arr));//第3趟排序for(int j=0;j<arr.length-1-2;j++){if(arr[j]>arr[j+1]){temp=arr[j];arr[j]=arr[j+1];arr[j+1]=temp;}}System.out.println("第3趟排序后的结果:"+Arrays.toString(arr));//第4趟排序for(int j=0;j<arr.length-1-3;j++){if(arr[j]>arr[j+1]){temp=arr[j];arr[j]=arr[j+1];arr[j+1]=temp;}}System.out.println("第4趟排序后的结果:"+Arrays.toString(arr));}//由于上面的一段代码在重复,只有可以arr.length-1后面减去的数字不同,正好是i,用for循环包括起来//于是有了冒泡排序的代码public static void BubbleSort(int []arr){int temp=0;for(int i=0;i<arr.length-1;i++){for(int j=0;j<arr.length-1-i;j++){if(arr[j]>arr[j+1]){temp=arr[j];arr[j]=arr[j+1];arr[j+1]=temp;}}System.out.println("第"+(i+1)+"趟排序后的结果"+ Arrays.toString(arr));}}//达到效果的另一种写法public static void BubbleSort3(int []arr){int temp=0;for(int i=arr.length-1;i>0;i--){for(int j=0;j<i;j++){if(arr[j]>arr[j+1]){temp=arr[j];arr[j]=arr[j+1];arr[j+1]=temp;}}System.out.println("第"+(arr.length-i)+"趟排序后的结果"+ Arrays.toString(arr));}}
}

运行结果:

6.优化

因为在排序过程中,各个元素不断接近自己的位置,如果一趟比较下来没有进行过交换,那么说明这个序列是有序的。既然有序那后面还需要在一轮一轮比较吗?不需要吧。所以我们可以在排序过程中设置一个标注flag判断元素是否进行过交换,减少不必要的比较。

优化后代码:

package com.xjj.sort;
import java.util.Arrays;
public class BubbleSort {public static void main(String[] args) {int arr[]={3,9,-1,10,20};BubbleSort4(arr);}//用于优化冒泡排序代码public static void BubbleSort4(int []arr){int temp=0;boolean flag=false;//标识变量,表示是否进行过交换for(int i=0;i<arr.length-1;i++){for(int j=0;j<arr.length-1-i;j++){if(arr[j]>arr[j+1]){flag=true;temp=arr[j];arr[j]=arr[j+1];arr[j+1]=temp;}}System.out.println("第"+(i+1)+"趟排序后的结果"+ Arrays.toString(arr));if(!flag){//也就是flag为false,在一趟排序中一次交换都没有发生break;}else{flag=false;//重置flag进行下一次判断,不然flag还是true的话到!flag时就是直接false,不会break了}}}
}

运行结果:

可以看到优化后,排序趟数减少了

再使得数组中原本就有序:1,2,3,4,5

运行结果:

一趟就可以,是不是感觉效率高多了!

7.优化后时间

插入段记录时间的代码。排序前记一次时间,排序后记一次时间。

然后输出元素的代码就先注释掉。

代码:

package com.xjj.sort;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
public class BubbleSort {public static void main(String[] args) {int arr[]={3,9,-1,10,20};BubbleSort4(arr);//测试时间int[] arr2=new int[80000];for(int i=0;i<80000;i++){arr2[i]=(int)(Math.random()*80000);//生成一个【0,80000】之间的随机数}Date date1=new Date();SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");String date1Str=simpleDateFormat.format(date1);System.out.println("排序前的时间为:"+date1Str);BubbleSort4(arr2);Date date2=new Date();String date2Str=simpleDateFormat.format(date2);System.out.println("排序后的时间为:"+date2Str);}//用于优化冒泡排序代码public static void BubbleSort4(int []arr){int temp=0;boolean flag=false;//标识变量,表示是否进行过交换for(int i=0;i<arr.length-1;i++){for(int j=0;j<arr.length-1-i;j++){if(arr[j]>arr[j+1]){flag=true;temp=arr[j];arr[j]=arr[j+1];arr[j+1]=temp;}}
//            System.out.println("第"+(i+1)+"趟排序后的结果"+ Arrays.toString(arr));if(!flag){//也就是flag为false,在一趟排序中一次交换都没有发生break;}else{flag=false;//重置flag进行下一次判断,不然flag还是true的话到!flag时就是直接false,不会break了}}}
}

运行结果:

80000个元素,优化后的冒泡排序运行时间8秒。


后面会继续写选择排序、插入排序等排序算法的内容。分类排序部分写完之后再给出一些题目练习^_^加油加油

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

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

相关文章

初识C语言——第十九天

for循环 1.简单概述 2.执行流程 3.建议事项&#xff1a;

ssm+vue的公务用车管理智慧云服务监管平台查询统计(有报告)。Javaee项目,ssm vue前后端分离项目

演示视频&#xff1a; ssmvue的公务用车管理智慧云服务监管平台查询统计&#xff08;有报告&#xff09;。Javaee项目&#xff0c;ssm vue前后端分离项目 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&…

Python运维之协程

目录 一、定义协程 二、并发 三、异步请求 协程是一种轻量级的线程&#xff0c;它通过保存和恢复寄存器上下文和栈来实现调度切换&#xff0c;从而保留函数执行的状态。 这种机制使得协程在处理I/O密集型任务时效率较高&#xff0c;因为它们可以在I/O操作期间让出CPU&#…

nacos在没有指定数据源的情况下默认使用什么数据库?

在没有特别指定数据源的情况下&#xff0c;Nacos 默认使用内嵌的数据库 Derby 来存储其数据。Derby 是一个轻量级的、基于 Java 的数据库管理系统&#xff0c;适合于开发和测试环境&#xff0c;因为它简单易部署且无需额外的数据库服务器。然而&#xff0c;对于生产环境&#x…

祝贺嫦娥六号发射成功,思迈特再为航天项目提供数据支持和保障

近日&#xff0c;嫦娥六号由长征五号遥八运载火箭在中国文昌航天发射场发射成功。 据悉&#xff0c;嫦娥六号是中国探月工程的第六个探测器&#xff0c;其主要任务是前往月球背面的南极-艾特肯盆地进行科学探测和样品采集。 嫦娥六号任务不仅是技术上的挑战&#xff0c;也是科学…

MySQL表结构的一些设计经验分享

我们在对一张表进行设计时&#xff0c;还要遵守一些基本的原则&#xff0c;比如经常听见的“范式准则”。但范式准则过于理论&#xff0c;在真实业务中&#xff0c;不必严格遵守三范式的要求。而且有时为了性能考虑&#xff0c;还可以进行反范式的设计&#xff0c;比如在数据仓…

知乎知+广告推广该如何做?怎么收费?

知乎作为一个汇聚高质量用户群体的知识分享平台&#xff0c;成为了众多品牌和产品推广的优选之地。特别是知乎的“知”广告推广服务&#xff0c;以其精准定向、内容原生的特点&#xff0c;深受广告主青睐。 一、知乎知广告推广基础 1. 什么是知乎知&#xff1f; 知是知乎官方…

C++--String类

系列文章目录 文章目录 目录 系列文章目录 文章目录 前言 一、为什么要学习string 1.c语言的字符串 2.OJ上的使用 二、string类的接口介绍 1.string简介 2.string构造成员函数 3.operator函数 4.string容器size和length 5.重载operator[]和引用返回的意义 5.1 oper…

使用git系统来更新FreeBSD ports源码

FreeBSD跟其它系统相比一大特色就是ports系统。 The Ports Collection is a set of Makefiles, patches, and description files. Each set of these files is used to compile and install an individual application on FreeBSD, and is called a port. By default, the Po…

使用Docker+Jar方式部署微服务工程(前后端分离)看着一篇就够了

本篇教程的使用到的技术有springboot、springcloud、Nacos、Docker、Nginx部署前后端分离访问的微服务。 部署一下Nacos 首先我们需要在服务器中&#xff08;或者本地部署启动一下Nacos&#xff09;&#xff0c;这里我采用服务器的方式进行部署&#xff0c;这里有一点不一样的…

# 从浅入深 学习 SpringCloud 微服务架构(十七)--Spring Cloud config(2)

从浅入深 学习 SpringCloud 微服务架构&#xff08;十七&#xff09;–Spring Cloud config&#xff08;2&#xff09; 一、springcloudConfig 入门案例&#xff1a;搭建 config 服务端 1、登录 码云&#xff1a;https://gitee.com/ 1&#xff09;点击右上角 【】 再点击【新…

算法学习笔记(一)-快速幂

#问题的引入-对于幂次方的求解我们怎么可以最大限度的降低时间复杂度呢 #对于一个基本的幂次运算&#xff0c;c代码如下示例 long long int myPower(int base,int power) {long long int result 1 ;for (int i 1 ; i < power ; i){result * base ;}return result ; } #…