数据结构---冒泡排序

2023-11-12

算法思想

把相邻的元素两两比较,当一个元素大于右侧相邻元素时,交换它们的位置;当一个元素小于或等于右侧相邻元素时,位置不变。
在这里插入图片描述
每次冒泡,就把当前最大的元素弄出来了。。。
在这里插入图片描述
在这里插入图片描述

冒泡排序是一种稳定排序,值相等的元素并不会打乱原本的顺序。由于该排序\算法的每一轮都要遍历所有元素,总共遍历(元素数量-1)轮,所以平均时间复杂度是O(n2)。

代码实现

使用双循环进行排序。外部循环控制所有的回合内部循环实现每一轮的冒泡处理,先进行元素比较,再进行元素交换。

    public static void sort(int array[]){
        for (int i=0;i<array.length-1;i++){
            for (int j=0;j<array.length-1-i;j++){
                int tmp = 0;
                //大的元素向右挪动
                if(array[j]>array[j+1]){
                    tmp = array[j];
                    array[j] = array[j+1];
                    array[j+1] = tmp;
                }
            }
        }
    }

在这里插入图片描述

优化冒泡排序1

在这里插入图片描述

如果能判断出数列已经有序,并做出标记,那么剩下的几轮排序就不必执行了,可以提前结束工作。

代码优化如下:利用布尔变量isSorted作为标记。如果在本轮排序中,元素有交换,则说明数列无序;如果没有元素交换,则说
明数列已然有序,然后直接跳出大循环。

package mysort.bubbleSort;

import java.util.Arrays;

public class bubbleSort2 {

    public static void sort(int array[]){
        for (int i = 0;i<array.length-1;i++){
            //有序标记,每一轮的初始值都是true
            boolean isSorted = true;
            for (int j = 0;j<array.length-1-i;j++){
                int tmp = 0;
                //大元素向后挪
                if(array[j]>array[j+1]){
                    tmp = array[j];
                    array[j] = array[j+1];
                    array[j+1] = tmp;
                    //因为有元素进行交换,所以不是有序的,标记变为false
                    isSorted = false;
                }
            }
            //一旦在一轮中没有元素交换了,说明之后的都有序了,就调出大循环
            //也就是:剩下的几轮排序就不必执行了,可以提前结束工作
            if(isSorted){
                break;
            }
        }
    }

    public static void main(String[] args) {
        int[] array = new int[]{5,8,6,3,9,2,1,7};
        sort(array);
        System.out.println(Arrays.toString(array));
    }
}

优化冒泡排序2

在这里插入图片描述
这个数列的特点是前半部分的元素(3、4、2、1)无序,后半部分的元素(5、6、7、8)按升序排列,并且后半部分元素中的最小值也大于前半部分元素的最大值。

问题在于:其实右面的许多元素已经是有序的了,可是每一轮还是白白地比较了许多次。

按照现有的逻辑,有序区的长度和排序的轮数是相等的。例如第1轮排序过后的有序区长度是1,第2轮排序过后的有序区长度是2 ……实际上,数列真正的有序区可能会大于这个长度,如上述例子中在第2轮排序时,后面的5个元素实际上都已经属于有序区了。因此后面的多次元素比较是没有意义的。

解决方案:我们可以在每一轮排序后,记录下来最后一次元素交换的位置,该位置即为无序数列的边界,再往后就是有序区了。

package mysort.bubbleSort;

import java.util.Arrays;

public class bubbleSort3 {
    public static void sort(int array[]){
        //记录最后一次交换的位置
        int lastExchangeIndex = 0;
        //无序数列的边界,每次比较只需要比到这里为止
        int sortBorder = array.length - 1;
        for (int i =0;i<array.length-1;i++){
            //有序标记,每一轮的初始值都是true
            boolean isSorted = true;
            for (int j = 0;j<sortBorder;j++ ){
                int tmp = 0;
                System.out.println("执行一次比较");
                //大元素后移
                if(array[j]>array[j+1]){
                    tmp = array[j];
                    array[j] = array[j+1];
                    array[j+1] = tmp;
                    //执行到这一步,说明有元素交换,所以不是无序,把标记isSorted置false
                    isSorted = false;
                    //更新为最后一次交换元素的位置
                    // 用于解决右面的许多元素已经是有序的了,可是每一轮中还是白白地比较了许多次的问题
                    lastExchangeIndex = j;
                }
            }
            //之前没有优化的代码里面是:array.length-1-i(这样就可以缩短每轮中比较的长度)
            sortBorder = lastExchangeIndex;
            //如果已经有序,直接跳出,减少比较轮次
            if(isSorted){
                break;
            }

        }
    }



    public static void main(String[] args) {
        int[]array = new int[]{3,4,2,1,5,6,7,8};
        sort(array);
        System.out.println(Arrays.toString(array));

    }
}


在这里插入图片描述

用没优化的冒泡排序代码如下:

    public static void sort2(int array[]){
        for (int i=0;i<array.length-1;i++){
            for (int j=0;j<array.length-1-i;j++){
                int tmp = 0;
                //大的元素向右挪动
                System.out.println("执行一次比较");
                if(array[j]>array[j+1]){
                    tmp = array[j];
                    array[j] = array[j+1];
                    array[j+1] = tmp;

                }
            }
        }
    }

在这里插入图片描述

sortBorder就是无序数列的边界。在每一轮排序过程中,处于sortBorder之后的元素就不需要再进行比较了,肯定是有序的。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

数据结构---冒泡排序 的相关文章

随机推荐

  • Java实现杨辉三角

    代码实现 package day01 public class yanghui public static void main String args 声明二维数组并初始化 int yanghui new int 10 给二维数组赋值 fo
  • jsp 新能源汽车论坛网Myeclipse开发mysql数据库web结构java编程计算机网页项目

    一 源码特点 JSP 新能源汽车论坛网是一套完善的java web信息管理系统 对理解JSP java编程开发语言有帮助 系统具有完整的源代码和数据库 系统主要采用B S模式开发 开发环境为 TOMCAT7 0 Myeclipse8 5开发
  • 《如何为Android Studio安装HAXM》

    注意 当你在Android studio直接下载sdk和HAXM一些安卓环境依赖的文件时 会出现haxm文件已经下载 但未安装 导致启动avd模拟器不成功 如下图 emulator64 x86 avd 32 QVGA ADP2 API 25
  • Python爬虫实战——搭建自己的IP代理池

    如今爬虫越来越多 一些网站网站加强反爬措施 其中最为常见的就是限制IP 对于爬虫爱好者来说 能有一个属于自己的IP代理池 在爬虫的道路上会减少很多麻烦 环境参数 工具 详情 服务器 Ubuntu 编辑器 Pycharm 第三方库 reque
  • sql增删改查_Zhuo笔记:使用C#链接SQL数据库并进行增删改查操作

    一 首先使用SQL语句在建立数据库及表 二 在C 中做一个简单窗口以便对SQL数据库进行操作 三 编写代码进行SQL链接 1 C 访问SQL SERVER首先需要引用using System Data 和usingSystem Data S
  • 芯片IO口Driving能力(Sourcing Current)测试方法

    PMOS管测试步骤 Drive High Ability 1 将IO PAD配置成output模式 DUT供电电压为可正常工作的最低电压 如依datasheet允许 下降10 3 3V gt 2 97V 等 2 将IO PAD配置成最大Dr
  • 图文详解GPT-4最强对手Claude2的使用方法

    大家好 我是herosunly 985院校硕士毕业 现担任算法研究员一职 热衷于机器学习算法研究与应用 曾获得阿里云天池比赛第一名 CCF比赛第二名 科大讯飞比赛第三名 拥有多项发明专利 对机器学习和深度学习拥有自己独到的见解 曾经辅导过若
  • 基于粒子群算法优化LSTM的多输入单输出台风风电功率预测

    基于粒子群算法优化LSTM的多输入单输出台风风电功率预测 随着风电产业的快速发展 风电场的管理和运行越来越依赖于准确的风速信息和风力预测 因此 台风风电功率预测的研究变得越来越重要 在本文中 我们将使用粒子群算法 PSO 来优化长短期记忆网
  • spring-boot项目使用ulisesbocchio对配置文件敏感信息加密

    参考文献github官网地址 https github com ulisesbocchio jasypt spring boot 1 添加依赖 maven
  • kiel5编译报错error: L6235E: More than one section matches selector - cannot all be FIRST/LAST.

    原因是startup xxx s文件只能保留其中一种 启动文件分别带有hd md ld和cl vl xl几种种字样 需要查看mcu的flash内存大小来选择 cl 互联型产品 stm32f105 107系列 vl 超值型产品 stm32f1
  • 世界各国英文简写一览表

    整理了一份世界各国英文简写表 供大家参考 country cName country code country eName 中国 CN China 中国台湾 W aiwan 中国澳门 MO Macao 中非共和国 CF he Central
  • 基于STM32c8t6的5路pwm占空比测量实验总结

    测量方式 1 正点原子例程里使用的方式 定时器通道的相关引脚输入捕获上升沿触发中断 在中断函数里 检测到上升沿之后TIM SetCounter TIMX 0 将计数器的值置零重新开始计数 同时将定时器中断触发方式切换为下降沿触发 待到下降沿
  • 嵌入式(TCP编程)

    TCP编程API 1 socket 函数 参数 2 bind 函数 如果是IPV6的编程 要使用 struct sockddr in6结构体 man 7 ipv6 通常更通用的方法可以通过struct sockaddr storage来编程
  • VulnHub渗透实战Billu_b0x

    简介 VulnHub是一个面向所有人开放的安全靶场 里面有很多安全环境 只要下载相关镜像 在相关虚拟机上面运行就可以练习相关靶场了 里面设计了好多关 如果有耐心一定可以到达峰顶 许多考oscp人员 也会利用vulnhub靶场进行刷题 我们下
  • pycharm缩进快捷键

    1 pycharm使多行代码同时右移缩进 鼠标选中多行代码后 按下Tab键 一次缩进四个字符 2 pycharm使多行代码同时左移 鼠标选中多行代码后 同时按住shift Tab键 一次左移四个字符
  • python函数和模块有什么特性_python-函数包和模块

    python函数的作用 在Python代码段中如果有一段几十行的代码 需要多次重复使用这几十行代码时 为了提高代码的可用性 将代码段放进函数体内 以后在使用中直接调用该函数模块即可 函数是一个独立的函数体或是一段独立的功能体 最主要的作用是
  • 头脑风暴会议的注意事项

    在组织内会经常召开头脑风暴的讨论会 如何举办一个成功的讨论会议呢 请看如下的30个要点 头脑风暴会议的注意事项 序号 分类 要点 1 会前 明确会议目的 议程 时间 地点 交通方式等 并确保通知到与会人员 以便参与者有充分准备 2 准备必要
  • 智能系统设计开发 java_一种基于java语言的智能系统设计与开发.doc

    一种基于java语言的智能系统设计与开发 doc 还剩 36页未读 继续阅读 下载文档到电脑 马上远离加班熬夜 亲 很抱歉 此页已超出免费预览范围啦 如果喜欢就下载吧 价低环保 内容要点 兰州交通大学毕业设计 论文 32参考文献 1 郭今吕
  • STM32 定时器的简单应用 1ms中断代码

    引言 利用定时器TIM8产生1ms中断 每中断一次 全局变量 1 计数到10即10ms 使得输出引脚翻转一次 芯片采用STM32F103VCT6 系统输入时钟12MHz 完成代码并用示波器输出 根据要求 本项目涉及系统时钟配置 中断源配置
  • 数据结构---冒泡排序

    冒泡排序 算法思想 代码实现 优化冒泡排序1 优化冒泡排序2 算法思想 把相邻的元素两两比较 当一个元素大于右侧相邻元素时 交换它们的位置 当一个元素小于或等于右侧相邻元素时 位置不变 每次冒泡 就把当前最大的元素弄出来了 冒泡排序是一种稳