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

news2024/11/25 1:02:50

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

目录

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.coloradmin.cn/o/1672779.html

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

相关文章

Java | Leetcode Java题解之第88题合并两个有序数组

题目&#xff1a; 题解&#xff1a; class Solution {public void merge(int[] nums1, int m, int[] nums2, int n) {int p1 m - 1, p2 n - 1;int tail m n - 1;int cur;while (p1 > 0 || p2 > 0) {if (p1 -1) {cur nums2[p2--];} else if (p2 -1) {cur nums1[p…

Vue的学习 —— <vue指令>

目录 前言 正文 内容渲染指令 内容渲染指令的使用方法 v-text v-html 属性绑定指令 双向数据绑定指令 事件绑定指令 条件渲染指令 循环列表渲染指令 侦听器 前言 在完成Vue开发环境的搭建后&#xff0c;若想将Vue应用于实际项目&#xff0c;首要任务是学习Vue的基…

黑马基于Web-socket的java聊天室基本解析

要是用Web-socket协议&#xff0c;我们要前端upgrade升级成web-socket协议 首先我们要引入springboot的websocket起步依赖&#xff0c;这样子方便使用&#xff0c;自己指定版本注意 <dependency><groupId>org.springframework.boot</groupId><artifactId&…

绘唐3启动器怎么启动一键追爆款3正式版

绘唐3启动器怎么启动一键追爆款3正式版 工具入口 一.文案助手&#xff1a; 【注意&#xff01;&#xff01;】如果图片无显示&#xff0c;一般情况下被杀毒拦截&#xff0c;需关闭杀毒软件或者信任文件路径。 win10设置排除文件&#xff1a; 1.【新建工程】使用前先新建工程…

std::ref和std::cref的使用和原理分析

目录 1.用法 2.std::reference_wrapper介绍 3.std::ref原理分析 4.std::cref原理分析 5.总结 1.用法 它的定义如下&#xff1a; std::ref&#xff1a;用于包装按引用传递的值。 std::cref&#xff1a;用户包装按const引用传递的值。 C本身就有引用&#xff08;&&#…

使用 Python 中的 TensorFlow 检测垃圾短信

前言 系列专栏&#xff1a;机器学习&#xff1a;高级应用与实践【项目实战100】【2024】✨︎ 在本专栏中不仅包含一些适合初学者的最新机器学习项目&#xff0c;每个项目都处理一组不同的问题&#xff0c;包括监督和无监督学习、分类、回归和聚类&#xff0c;而且涉及创建深度学…

【鸿蒙开发】第二十四章 IPC与RPC进程间通讯服务

1 IPC与RPC通信概述 IPC&#xff08;Inter-Process Communication&#xff09;与RPC&#xff08;Remote Procedure Call&#xff09;用于实现跨进程通信&#xff0c;不同的是前者使用Binder驱动&#xff0c;用于设备内的跨进程通信&#xff0c;后者使用软总线驱动&#xff0c;…

一个基于servlet的MVC项目-登录验证

一、MVC的概念 MVC是Model、View、Controller的缩写&#xff0c;分别代表 Web 应用程序中的3种职责1 模型:用于存储数据以及处理用户请求的业务逻辑。 2视图:向控制器提交数据&#xff0c;显示模型中的数据。 3控制器:根据视图提出的请求&#xff0c;判断将请求和数据交给哪个…

Linux下网络命令

目录 需求1-查看本机是否存在22端口解法1解法2解法3 需求2-查看其他主机是否存在22端口解法1解法2解法3 需求3-查看TCP连接解法1/2 需求4-统计80端口tcp连接次数解法 需求5-查看总体网络速度解法 需求6-查看进程流量解法 需求7-dns解法 需求8-traceroute到baidu解法 需求9-查看…

git仓库使用

git仓库是会限制空间大小限制的 git网络库的容量限制_github仓库大小限制-CSDN博客 git是用于管理github的工具 电脑左下角搜索git打开GitBash.exe 进入到要下载到本地的目录 下载到本地的文件不要更改&#xff01; 如果要使用请务必把文件复制到别的空间去再在这个别的空间…

centos7中查询Nacos的安装路径和配置信息如何查找?

在 CentOS 7 上查询 Nacos 的安装路径和配置信息通常涉及几个步骤。这些步骤主要依赖于你是如何安装 Nacos 的&#xff08;比如使用压缩包还是 Docker 等方式&#xff09;。下面是一些通用的方法来帮助你找到 Nacos 的安装路径和配置信息&#xff1a; 1. 查找 Nacos 的安装路径…

智能自助终端主板RK3288/RK3568在酒店前台自助机方案的应用,支持鸿蒙,支持免费定制

酒店前台自助机解决方案是一款基于自助服务终端&#xff0c;能够让客人通过简单的操作完成入住登记/退房的解决方案&#xff0c;大幅提高酒店的工作效率&#xff0c;提升客人体验&#xff0c;降低人力成本。 该方案解决了以下传统前台登记入住方式的痛点&#xff1a; 1、人流量…

elasticsearch 动态映射

文章目录 动态映射动态映射的弊端静态映射实战&#xff1a;映射创建后还可以更新吗 动态映射 动态映射的核心是在自动检测字段类型后添加新字段 哪些字段类型支持动态检测呢&#xff1f; 答&#xff1a;boolean类型、float类型、long类型、Object类型、Array类型、date类型、…

Hive-表设计优化

Hive-表设计优化 1.Hive查询基本原理 Hive的设计思想是通过元数据解析描述将HDFS上的文件映射成表。 基本的查询原理是当用户通过HQL语句对Hive中的表进行复杂数据处理和计算时&#xff0c;默认将其转换为分布式计算MapReduce程序对HDFS中的数据进行读取处理的过程。 当执行…

黑马甄选离线数仓项目day02(数据采集)

datax介绍 官网&#xff1a; https://github.com/alibaba/DataX/blob/master/introduction.md DataX 是阿里云 DataWorks数据集成 的开源版本&#xff0c;在阿里巴巴集团内被广泛使用的离线数据同步工具/平台。 DataX 实现了包括 MySQL、Oracle、OceanBase、SqlServer、Postgre…

48-Qt控件详解:Buttons Containers2

一 Group Box:组合框 #include "widget.h"#include<QGroupBox> #include<QRadioButton> #include<QPushButton> #include<QVBoxLayout>//可以在水平方向和垂直方向进行排列的控件&#xff0c;QHBoxLayout/QVBoxLayout #include <QGridLa…

Adobe Media Encoder ME v24.3.0 解锁版 (视频和音频编码渲染工具)

Adobe系列软件安装目录 一、Adobe Photoshop PS 25.6.0 解锁版 (最流行的图像设计软件) 二、Adobe Media Encoder ME v24.3.0 解锁版 (视频和音频编码渲染工具) 三、Adobe Premiere Pro v24.3.0 解锁版 (领先的视频编辑软件) 四、Adobe After Effects AE v24.3.0 解锁版 (视…

新增柱线组合图、象限图,新增钉钉、飞书、企业微信客户端免密登录,DataEase开源数据可视化分析工具v2.6.0发布

2024年5月13日&#xff0c;人人可用的开源数据可视化分析工具DataEase正式发布v2.6.0版本。 这一版本的功能升级包括&#xff1a;图表方面&#xff0c;新增了柱线组合图、象限图&#xff1b;仪表板方面&#xff0c;支持批量拖拽字段&#xff0c;外部参数新增支持配置过滤组件&…

云原生基础设施和操作系统分论坛 03-在Kubernetes上运行Apache Spark进行大规模数据处理的实践【数据分析】

https://spark.apache.org/视频观看&#xff1a;https://www.bilibili.com/video/BV17J4m1n7Gv/?spm_id_from333.999.0.0 简介 Apache Spark 是专为大规模数据处理而设计的快速通用的计算引擎。Spark是UC Berkeley AMP lab (加州大学伯克利分校的AMP实验室)所开源的类Hadoop…

/proc/modules文件

/proc/modules文件中列出了内核加载的所有模块的信息&#xff0c;与使用lsmod命令类似。 第一列&#xff1a;模块名称 第二列&#xff1a;模块使用的内存大小&#xff0c;单位是bytes 第三列&#xff1a;模块被load的次数 第四列&#xff1a;是否有其他模块依赖此模块&#…