八大排序算法--冒泡排序(动图理解)

news2024/12/24 20:11:40

冒泡排序

算法思路

冒泡排序的原理是:从左到右,相邻元素进行比较。每次比较一轮,就会找到序列中最大的一个或最小的一个。这个数就会从序列的最右边冒出来。

以从小到大排序为例,第一轮比较后,所有数中最大的那个数就会浮到最右边;第二轮比较后,所有数中第二大的那个数就会浮到倒数第二个位置……就这样一轮一轮地比较,最后实现从小到大排序。
 

动画演示

 

算法代码

 public static void bubbleSort(int[] a){
    for (int i = 0; i < a.length-1; i++) {//a.length-1是因为不用与自己比较,所以比的数就少一个
         for (int j = 0; j < a.length-1-i; j++){//a.lenght-1-i是因为每一趟就会少一个数比较
             if(a[j]>a[j+1]){
                  int tmp = a[j];
                  a[j] = a[j+1];
                  a[j+1]  = tmp;
             }
         }
     }
  }

上面代码还有些不足,如果一个序列本来就有序,或者在排序的中间部分就已经排好序。但冒泡排序仍然会走完两个for循环, 时间复杂度一直为O(n^2) 。 为此我们可以改进代码,在每次比较开始前,都加一个flag标记,若交换了数,则改变flag,说明序列还未有序。 若在一趟比较完后,flag没变,则说明序列已经有序,就不用再进行循环了。此时时间复杂度最好可变为O(n)

优化后

 public static void bubbleSort(int[] a){

        for (int i = 0; i < a.length-1; i++) {
            int flag = 0;  //添加标记
            for (int j = 0; j < a.length-1-i; j++) {
                if(a[j]>a[j+1]){
                    int tmp = a[j];
                    a[j] = a[j+1];
                    a[j+1]  = tmp;
                    falg++;
                }
            }
            if(flag==0) break; //即falg在经过for循环后,还为0 说明已排好序了,就不用再进行排序
        }                      
    }

复杂度分析

时间复杂度 O(n^2)   优化后 最好情况变为 o(n)

时间复杂度测试

接下来我们试着用大量数据测试一下。

int[] a = new int[10_0000];  //10万个数据测试

1.orderArray函数实现生成一个基本有序数列,即从小到大排列。

public static void orderArray(int[] a) {
        for (int i = 0; i < a.length; i++) {
            a[i] = i;
        }
 }

2.notOrderArray函数生成一个倒序数列,即从大到小排列。

public static void notOrderArray(int[] a) {
        for (int i = 0; i < a.length; i++) {
            a[i] = a.length-i;
        }
}

3.randomArray函数生成一个随机无序数列。

 public static void randomArray(int[] a) {
        Random random = new Random();
        for (int i = 0; i < a.length; i++) {
            a[i] = random.nextInt(10_0000);
        }
 }

4.testInsertSort函数测试   System.currentTimeMillis() 返回值单位是毫秒。

 public static void testInsertSort(int[] a){
        int[] tmpArray = Arrays.copyOf(a,a.length);
        long startTime = System.currentTimeMillis();    //注意用long接收
        shellSort(tmpArray);
        long endTime = System.currentTimeMillis();  //返回单位是毫秒
        System.out.println("冒泡排序耗时:"+(endTime-startTime));
 }

5.main函数调用执行

public static void main(String[] args) {
 
 
        int[] a = new int[10_0000];
        //有序
        System.out.println("基本有序数列");
        orderArray(a);
        testInsertSort(a);
 
        //倒序
        System.out.println("逆序数列");
        notOrderArray(a);
        testInsertSort(a);
 
        //随机乱序
        System.out.println("无序数列");
        randomArray(a);
        testInsertSort(a);
 
}

运行结果

    

 通过比较,发现改进后的时间复杂度还是有所下降的。

完整代码

import java.util.Random;

public class sort {

    public static void main(String[] args) {
    
        int[] a = new int[10_0000];
        
        //有序
        System.out.println("基本有序数列");
        orderArray(a);
        testInsertSort(a);

        //无序
        System.out.println("逆序数列");
        notOrderArray(a);
        testInsertSort(a);

        //乱序
        System.out.println("无序数列");
        randomArray(a);
        testInsertSort(a);

    }


    //冒泡排序
    //时间复杂度 O(n^2)   优化后 最好情况 O(n)
    public static void bubbleSort(int[] a){
        for (int i = 0; i < a.length; i++) {
            for (int j = 0; j < a.length-1-i; j++) {
                if(a[j]>a[j+1]){
                    int tmp = a[j];
                    a[j] = a[j+1];
                    a[j+1]  = tmp;
                }
            }
        }
    }


    //优化后的冒泡排序
    public static void bubbleSort1(int[] a){

        for (int i = 0; i < a.length; i++) {
            int flag = 0;
            for (int j = 0; j < a.length-1-i; j++) {
                if(a[j]>a[j+1]){
                    int tmp = a[j];
                    a[j] = a[j+1];
                    a[j+1]  = tmp;
                    flag++;
                }
            }
            if(flag==0) break;
        }
    }


    //生成有序数组  从小到大排列
    public static void orderArray(int[] a) {
        for (int i = 0; i < a.length; i++) {
            a[i] = i;
        }
    }


    //n无序 其实就是从大到小排列
    public static void notOrderArray(int[] a) {
        for (int i = 0; i < a.length; i++) {
            a[i] = a.length-i;
        }
    }

    //乱序 随机生成序列
    public static void randomArray(int[] a) {
        Random random = new Random();
        for (int i = 0; i < a.length; i++) {
            a[i] = random.nextInt(10_0000);
        }
    }

    //大量数据测试
    public static void testInsertSort(int[] a){
        int[] tmpArray = Arrays.copyOf(a,a.length);
        long startTime = System.currentTimeMillis();    //注意用long接收
        bubbleSort1(tmpArray);
        long endTime = System.currentTimeMillis();
        System.out.println("改进冒泡排序耗时:"+(endTime-startTime));
    }

}

创作不易,如果本篇博客对您有一定的帮助,大家记得留言+点赞哦。

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

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

相关文章

多重背包三队列优化的理解以及代码记忆:

首先是多重背包得一维朴素版本&#xff08;除了完全背包和多重背包得队列优化都是从大到小&#xff09;&#xff1a; 通过这个执行过程我们发现这个是分类更新得&#xff0c;可以按照余数是进行更新&#xff0c;而且物品数量最多有三件&#xff0c;物品数量决定了窗口的宽度所…

JAVA基础知识-进制的介绍与书写格式

1. 进制的介绍与书写格式 1.1 进制的介绍与书写格式 代码 : public class Demo1 {/*十进制&#xff1a;Java中&#xff0c;数值默认都是10进制&#xff0c;不需要加任何修饰。二进制&#xff1a;数值前面以0b开头&#xff0c;b大小写都可以。八进制&#xff1a;数值前面以0开…

TDesign中后台管理系统-访问后端服务

目录 1 修改后端服务地址2 解决跨域问题3 动态获取菜单4 测试后端接口5 前后端联调总结 目前我们已经搭建了TDesign的前端和express的后端&#xff0c;目前是两个独立的应用。通常我们需要把前后端集成在一起&#xff0c;TDesign已经配置了相关的信息&#xff0c;只需要修改后端…

内存分析工具之Mat

自定义类MatClazz内存个数为9521。当前对象占用内存为16个字节。不包括其属性bytes的字节数。 通过查看MatClazz引用的类之byte数组之bytes。其单个数组占用的字节数为10256。整个内存MatClazz中属性bytes占用的byte[]字节数为97746376&#xff0c;与直方图统计趋近。 通过选…

Mac 终端快捷键设置:如何给 Mac 中的 Terminal 设置 Ctrl+Alt+T 快捷键快速启动

Mac 电脑中正常是没有直接打开终端命令行的快捷键指令的&#xff0c;但可以通过 commandspace 打开聚焦搜索&#xff0c;然后输入 ter 或者 terminal 全拼打开。但习惯了 linux 的同学会觉得这个操作很别扭。于是我们希望能通过键盘按键直接打开。 操作流程如下&#xff1a; 1…

Linux的xshell和xftp工具的使用

这里写目录标题 第一章、xshell工具和xftp的使用1.1&#xff09;xshell下载与安装1.2&#xff09;xshell连接1.3&#xff09;xftp下载安装和连接1.4&#xff09;xftp使用 第一章、xshell工具和xftp的使用 1.1&#xff09;xshell下载与安装 ①用来远程操作Linux虚拟机系统 两个…

Mac 安装配置adb命令环境(详细步骤)

一、注意&#xff1a;前提要安装java环境。 因为android sdk里边开发的一些包都是依赖java语言的&#xff0c;所以&#xff0c;首先要确保已经配置了java环境。 二、在Mac下配置android adb命令环境&#xff0c;配置方式如下&#xff1a; 1、下载并安装IDE &#xff08;andr…

python+opencv实现显示摄像头,截取相关图片,录取相关视频

实时显示摄像头图像 按下空格键&#xff0c;截取图片 按下tab键&#xff0c;开始录制摄像内容&#xff0c;再次按下&#xff0c;结束录制 按下Esc键&#xff0c;关闭窗口 import cv2 import numpy#第几章图片 img_count0InitVideoFalse #第几个视频 video_count0 video_flagFa…

分治法 Divide and Conquer

1.分治法 分治法&#xff08;Divide and Conquer&#xff09;是一种常见的算法设计思想&#xff0c;它将一个大问题分解成若干个子问题&#xff0c;递归地解决每个子问题&#xff0c;最后将子问题的解合并起来得到整个问题的解。分治法通常包含三个步骤&#xff1a; 1. Divid…

C 语言 - 存储类说明符

【预备知识】 1&#xff09;C 语言 - 存储时期 2&#xff09;C 语言 - 链接属性 3&#xff09;C 语言 - 作用域 1. 分类&#xff1a; C 语言为变量提供了 5 中不同的存储模型&#xff08;即存储类&#xff09;。 &#xff08;此外还有基于指针的第 6 种存储模型&#xff0c…

【外卖系统】文件上传与下载

文件上传 文件上传又称upload&#xff0c;将本地图片、视频等文件上传到服务器上&#xff0c;供其他用户下载或者浏览。 form表单&#xff1a;HTML中的form元素用于创建一个包含表单字段的区域&#xff0c;用户可以在该区域输入数据&#xff0c;并通过提交表单将数据发送到服务…

MySQL初探

Background 通过阅读小林coding&#xff0c;大致了解了mysql数据库的种种特点&#xff0c;与之前学的数据库实现大体思路相同&#xff0c;感觉学习不能停留在理论层面&#xff0c;要调研生产级别的中间件实现。 一条代码运行在mysql上的流程 1. 连接的过程需要先经过 TCP 三次…

[回馈]ASP.NET Core MVC开发实战之商城系统(四)

经过一段时间的准备&#xff0c;新的一期【ASP.NET Core MVC开发实战之商城系统】已经开始&#xff0c;在之前的文章中&#xff0c;讲解了商城系统的整体功能设计&#xff0c;页面布局设计&#xff0c;环境搭建&#xff0c;系统配置&#xff0c;及首页【商品类型&#xff0c;ba…

Structure Guided Lane Detection 论文精度

结构导向车道检测 摘要 近年来&#xff0c;随着深度神经网络和自动驾驶的快速发展&#xff0c;车道检测取得了长足的进步。然而&#xff0c;主要存在三个问题&#xff0c;包括车道的特征化、场景与车道之间的结构关系建模以及对车道的更多贡献&#xff08;如实例和类型&#…

手搓 自然语言模型 各种对比数据

基础模型和设计思想 最优网络结构 import paddle import numpy as np from tqdm import tqdm class EmMask(paddle.nn.Layer):def __init__(self, voc_size19, hidden_size256, max_len48):super(EmMask, self).__init__()# 定义输入序列和标签序列self.embedding_layer pad…

Unity3d C#快速打开萤石云监控视频流(ezopen)支持WebGL平台,替代UMP播放视频流的方案(含源码)

前言 Universal Media Player算是视频流播放功能常用的插件了&#xff0c;用到现在已经不知道躺了多少坑了&#xff0c;这个插件虽然是白嫖的&#xff0c;不过被甲方和领导吐槽的就是播放视频流的速度特别慢&#xff0c;可能需要几十秒来打开监控画面&#xff0c;等待的时间较…

我的第一个前端(VS code ,Node , lite-server简易服务器,npm 运行)

第一种方式&#xff1a;使用Visual Studio Code创建并运行 第一个前端项目的步骤&#xff0c;如下&#xff1a; 1. 下载和安装Visual Studio Code&#xff1a; 访问Visual Studio Code官方网站&#xff08;Visual Studio Code - Code Editing. Redefined&#xff09;并根据你…

二十三种设计模式第二十篇--备忘录模式

备忘录模式&#xff0c;备忘录模式属于行为型模式。它允许在不破坏封装的情况下捕获和恢复对象的内部状态。保存一个对象的某个状态&#xff0c;以便在适当的时候恢复对象&#xff0c;该模式通过创建一个备忘录对象来保存原始对象的状态&#xff0c;并将其存储在一个负责管理备…

133. 克隆图

给你无向 连通 图中一个节点的引用&#xff0c;请你返回该图的 深拷贝&#xff08;克隆&#xff09;。 图中的每个节点都包含它的值 val&#xff08;int&#xff09; 和其邻居的列表&#xff08;list[Node]&#xff09;。 class Node { public int val; public List&…

互联网医院系统开发:打造便捷高效的医疗服务平台

随着互联网技术的飞速发展&#xff0c;互联网医院系统的出现为医疗行业带来了许多新的机遇和优势。互联网医院系统是一种基于互联网技术的医疗服务平台&#xff0c;旨在提供便捷、高效、个性化的医疗服务。下面将介绍互联网医院系统开发的优势。   提供便捷的医疗服务&#x…