首页 > 其他分享 >Day26--冒泡排序

Day26--冒泡排序

时间:2024-10-31 11:49:21浏览次数:1  
标签:遍历 -- 复杂度 Day26 冒泡排序 int array 比较

Day26--冒泡排序

冒泡排序无疑是最为出名的排序算法之一:总共有八大排序

冒泡的代码还是相当简单的,两层循环:外层冒泡轮数,里层依次比较:江湖中人人尽皆知。

我们看到嵌套循环:应该立马就可以得出这个算法的时间复杂度为 O (n²)。思考:如何优化?

1. 冒泡排序的思路理解:

一、冒泡排序的起名由来:

冒泡排序的主要思想是通过多次遍历要排序的数列,每次比较相邻的两个元素,如果它们的顺序错误就把它们交换过来。

这样经过多次遍历,最大(或最小)的元素就会像气泡一样 “浮” 到数列的顶端。

二、具体过程

  1. 第一轮遍历:
    • 从数列的第一个元素开始,依次比较相邻的两个元素。
    • 如果前一个元素比后一个元素大,就交换它们的位置。
    • 这样在第一轮遍历结束后,最大的元素就会被 “冒泡” 到数列的最后一个位置。
  2. 第二轮遍历:
    • 由于最大的元素已经在最后位置,所以第二轮遍历只需要对前面的 n - 1 个元素进行操作。
    • 重复第一轮的比较和交换过程,将第二大的元素 “冒泡” 到数列的倒数第二个位置。
  3. 依此类推:
    • 每一轮遍历都将未排序部分中的最大元素 “冒泡” 到相应位置。
    • 经过 n - 1 轮遍历后,整个数列就完成了排序。

三、示例说明

假设有一个整数数列 [8, 5, 2, 4, 3]。

  1. 第一轮遍历:

    • 比较 8 和 5,因为 8 > 5,所以交换位置,数列变为 [5, 8, 2, 4, 3]。

    • 比较 8 和 2,交换位置,变为 [5, 2, 8, 4, 3]。

    • 比较 8 和 4,交换位置,变为 [5, 2, 4, 8, 3]。

    • 比较 8 和 3,交换位置,变为 [5, 2, 4, 3, 8]。此时第一轮遍历结束,最大的元素 8 被 “冒泡” 到了最后位置。

  2. 第二轮遍历:

    • 比较 5 和 2,交换位置,变为 [2, 5, 4, 3, 8]。

    • 比较 5 和 4,交换位置,变为 [2, 4, 5, 3, 8]。

    • 比较 5 和 3,交换位置,变为 [2, 4, 3, 5, 8]。第二轮结束,第二大的元素 5 被 “冒泡” 到了倒数第二个位置。

      和第一轮相比,少了一次比较

  3. 第三轮遍历:

    • 比较 2 和 4,不交换位置,数列仍为 [2, 4, 3, 5, 8]。

    • 比较 4 和 3,交换位置,变为 [2, 3, 4, 5, 8]。第三轮结束,第三大的元素 4 被 “冒泡” 到了相应位置。

      和第二轮相比,少了一次比较

  4. 第四轮遍历:

    • 比较 2 和 3,不交换位置,数列保持 [2, 3, 4, 5, 8] 不变。第四轮结束,整个数列完成排序。

      和第三轮相比,少了一次比较

四、具体分析

从第二轮遍历开始,每一轮遍历,都比上一轮少一次比较。

每一轮遍历,都会产生出一个最大或者最小的数,排在最前面或者最后面,因此比较次数少一次

遍历的轮数:array.length-1

五、时间复杂度和空间复杂度

元素个数:n; 遍历轮数: i

  1. 时间复杂度:

    • 最坏情况下,即数列是逆序的,需要进行 n - 1 轮遍历,每一轮遍历都要比较和交换 n - i 次(i 表示当前轮数),所以总的比较和交换次数为 n (n - 1)/2,时间复杂度为 O (n²)。
    • 最好情况下,即数列已经是有序的,只需要进行一轮遍历就可以完成排序,时间复杂度为 O (n)。不过这种情况出现的概率较低。
  2. 空间复杂度:

    • 冒泡排序是一种原地排序算法,只需要常数级别的额外空间,所以空间复杂度为 O (1)。
  3. 时间复杂度的理解:以冒泡排序为例:

    在计算机科学中,时间复杂度为 O (n²) 表示算法的运行时间与输入数据规模 n 的平方成正比。

    具体来说,当输入数据规模为 n 时,算法的执行时间可以用一个包含 n² 的表达式来近似表示。例如,如果一个算法对于规模为 n 的输入数据需要执行 n² 次基本操作,那么这个算法的时间复杂度就是 O (n²)。

    以冒泡排序为例,它有两层循环,外层循环执行 n - 1 次(n 为待排序数据的数量),内层循环在每一轮外层循环中执行的次数逐渐减少,但总体上也与 n 相关。对于一个包含 n 个元素的列表进行冒泡排序,大约需要比较和交换的次数为 n (n - 1)/2,当 n 很大时,这个数量级接近 n²,所以冒泡排序的时间复杂度为 O (n²)。

n (n - 1)/2的计算:

n-1+n-2+n-3+...+n-n=n*n-(1+2+...+n)=n *2 n/2-n (n + 1)/2=n/2 * (n-1)

2.冒泡排序的示例

从小到大排序

package com.liu.www.array;

import java.util.Arrays;

public class ArrayDemo07 {
    public static void main(String[] args) {
        int[] a={1,3,2};
        sort(a);
        System.out.println(Arrays.toString(a));


    }
    //冒泡排序
    //1. 比较两个相邻的元素大小。不行就交换位置,来满足:大的排后边,小的排前面
    //2. 每一轮遍历,都会产生出一个最大或者最小的数
    //3.下一轮可以少一次比较
    //4.以此类推,直到结束


    //下面的方法是从小往大排序
    public static int[] sort(int[] array){
        int temp=0;
        //外层循环:判断循环的次数
        for (int i = 0; i < array.length-1; i++) {
            //内层循环:比较两个数的位置。如果第一个数比第二个数大,则交换位置
            for (int j = 1; j <array.length-1-i; j++) {
                if(array[j]>array[j+1]){
                    temp=array[j+1];
                    array[j+1]=array[j];
                    array[j]=temp;
                }
            }
        }return array;

    }
    /*
    1 4 2 3   arrays.length=4                     i=0;i<3    j=0;j<3
    1    4                         1423                      j=0;j<3
    4    2--->   2     4           1243                      j=1;j<3
    4    3--->   3     4           1234                      j=2;j<3

     */
}

优化:

当已经排好序的时候,就可以节省遍历次数了

//下面的方法是从小往大排序
    public static int[] sort(int[] array){
        int temp=0;
        boolean flag=true;//通过flag标识符,减少没有意义的比较
        //外层循环:判断循环的次数
        for (int i = 0; i < array.length-1; i++) {
            //内层循环:比较两个数的位置。如果第一个数比第二个数大,则交换位置
            for (int j = 0; j <array.length-1-i; j++) {
                if(array[j]>array[j+1]){
                    temp=array[j+1];
                    array[j+1]=array[j];
                    array[j]=temp;
                    flag=false;
                }
                if(flag==true){
                    break;
                }
            }
        }return array;

    }

通过flag标识符,减少没有意义的比较。

标签:遍历,--,复杂度,Day26,冒泡排序,int,array,比较
From: https://www.cnblogs.com/xiaokunzhong/p/18517417

相关文章

  • Python+Django框架山西太原二手房数据可视化大屏系统开题报告参考
     博主介绍:黄菊华老师《Vue.js入门与商城开发实战》《微信小程序商城开发》图书作者,CSDN博客专家,在线教育专家,CSDN钻石讲师;专注大学生毕业设计教育、辅导。所有项目都配有从入门到精通的基础知识视频课程,学习后应对毕业设计答辩,提供核心代码讲解,答辩指导。项目配有对应开发......
  • 小白手把手教学用spring框架实现mybatis和mysql以及工作原理
    Maven_Mybatis_Mysql什么是MybatisMyBatis是一款优秀的持久层框架,它支持自定义SQL、存储过程以及高级映射。MyBatis免除了几乎所有的JDBC代码以及设置参数和获取结果集的工作。MyBatis可以通过简单的XML或注解来配置和映射原始类型、接口和JavaPOJO(PlainOldJavaObj......
  • AdaBoost与前向分步算法
    1.加性模型的定义在AdaBoost算法中,我们可以将其视为一种加性模型。加性模型是指由多个基模型的线性组合构成的模型。图中的公式(10-9)描述了加性模型的形式:f(......
  • qsort排序
    在体操比赛中,每位选手的得分是由多名裁判综合打分所得。现在已经汇总了N名选手的个人总得分(选手的编号依次为1,2,……N),请你设计程序找出第K名选手在所有选手中的排名。输入说明:第一行是N和K,N表示运动员的个数,K是选手序号;第二行依次是这N位运动员的个人总得分。输出说明:第K名(从1开......
  • 庖丁解java(一篇文章学java)
    (大家不用收藏这篇文章,因为这篇文章会经常更新,也就是删除后重发) 一篇文章学java,这是我滴一个执念...当然,真一篇文章就写完java基础,java架构,java业务实现,java业务扩展,根本不可能.所以,这篇文章,就是一个索引,索什么呢?  请看下文...关于决定开始写博文的介绍......
  • 达梦客户端/idea连接达梦/达梦导出
    达梦自带的工具导出非常有缺陷大问题,所以使用idea连接达梦进行导出 一,下载达梦jdbc驱动达梦官网产品下载|达梦数据库(dameng.com)     二,idea添加driver在IntelliJIDEA中连接达梦数据库,可以按照以下步骤进行操作:1.打开IntelliJIDEA,进入项目。2.......
  • MongoDB 部署指南:从 Linux 到 Docker 的全面讲解
    一、MongoDB简介MongoDB是一种NoSQL数据库,以文档模型存储数据,具备高性能、弹性扩展性和分布式架构等特点,非常适用于高并发和大数据量的场景。本文将从Linux和Docker环境开始讲解,帮助读者在不同环境下顺利部署MongoDB。二、在Linux(CentOS)上部署MongoDB2.1......
  • 【双端广搜】字符串接龙
    110.字符串接龙#include<iostream>#include<cstring>#include<algorithm>#include<queue>#include<unordered_map>usingnamespacestd;constintN=510;intn;stringword[N];//如果两个队列共用st数组,那么两个队列永远不会碰头//因为在入队时我们会con......
  • Spring Boot应用MongoDB
    1.添加Maven依赖在SpringBoot项目中,引入spring-boot-starter-data-mongodb依赖:<dependencies><!--MongoDBstarterdependencyforSpringBoot--><dependency><groupId>org.springframework.boot</groupId><......
  • 【GeoScene】五、影像TIF创建tpk切片缓存并发布
    阿巴阿巴.....,我这拖延症也是没谁了,还是来个总结吧,好歹让自己以后有迹可循;一定要看到最后再去尝试,一路的坑原本觉得这不简简单单嘛,还需要写?不对,这还需要查教程吗?然后劈里啪啦一通操作......什么鬼啊,这么简单的操作还失败???我的姿势不对?然后又尝试了一次......不出意外一样的问......