基础算法02——冒泡排序(Bubble Sort)

embedded/2025/3/27 10:40:32/

冒泡排序(Bubble Sort)

  1. 冒泡排序:是一种简单的排序算法,其基本思想是通过重复遍历要排序的列表,比较相邻的元素,并在必要时(即前面的数比后面的数大的时候)交换它们的位置,从而将较大的元素逐渐“冒泡”到列表的末尾。这个过程会重复进行(第一次把最大的元素放在列表的末尾,第二次把第二大的元素放在列表的倒数第二的位置,以此类推,只需执行(数组的长度-1次)这个过程即可),直到整个列表被排序。
    • 冒泡排序主要有两个for循环组成
      • 外层for循环主要用于控制数组循环遍历的次数
        • 数组的长度决定要遍历的次数
      • 内层for循环主要用于元素位置的交换(把较大的元素往后移动)

冒泡排序初代代码:减少比较次数

  • 优化点:每经过一轮冒泡,内层循环就可以减少一次
java">public class BubbleSort {public static void main(String[] args) {int[] arr ={24,69,80,57,13};System.out.println("排序前的数组:");printArray(arr);bubbleSort(arr);System.out.println("排序后的数组:");printArray(arr);}/*** 冒泡排序算法* @param arr:数组*/public static void bubbleSort(int[] arr) {int n = arr.length; // 数组长度// 外层循环是控制数组循环遍历的次数:默认要循环【数组的长度-1】遍,每遍历一次子循环的比较次数就减少一次(因为每次子循环会把最大的一个元素放在数组的最后)for (int i = 0; i < n - 1; i++) {// 内层循环控制每一次循环的比较和元素的交换(一轮冒泡)for (int j = 0; j < n - 1 - i; j++) {  // n-1-i表示要比较的元素的个数if (arr[j] > arr[j + 1]) { // 如果前一个元素大于后一个元素,则交换int temp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = temp;swapped = true; // 当数组元素发生交换说明数组当前不是有序的}}}}// 打印数组public static void printArray(int[] arr) {for (int num : arr) {System.out.print(num + " ");}System.out.println();}}

案例分析

  1. 以int[] arr= {24,69,80,57,13};举例
    • 外层for循环第1轮:把最大的数放在最后的位置
      • 前一个数和后一个数比较,如果前者大就交换位置(内层for循环)
        • 第1次比较[24,69,80,57,13] 第1个和第2个比
        • 第2次比较[24,69,80,57,13] 第2个和第3个比
        • 第3次比较[24,69,57,80,13] 第3个和第4个比(80比57大,所以80和57交换位置
        • 第4次比较[24,69,57,13,80] 第4个和第5个比(80比13大,所以80和13交换位置
    • 外层for循环第2轮:把第二大的数放在倒数第二个位置
      • 前一个数和后一个数比较,如果前者大就交换位置(内层for循环)
        • 第1次比较[24,69,57,13,80] 第1个和第2个比
        • 第2次比较[24,57,69,13,80] 第2个和第3个比
        • 第3次比较[24,57,13,69,80] 第3个和第4个比
    • 外层for循环第3轮:把第三大的数放在倒数第三个位置
      • 前一个数和后一个数比较,如果前者大就交换位置(内层for循环)
        • 第1次比较[24,57,13,69,80] 第1个和第2个比
        • 第2次比较[24,13,57,69,80] 第2个和第3个比
    • 外层for循环第4轮:把第四大的数放在倒数第四个位置
      • 前一个数和后一个数比较,如果前者大就交换位置(内层for循环)
        • 第1次比较[13,24,57,69,80] 第1个和第2个比
  • 总结
      1. 一共有5个元素(数组的长度为n,n=5)
      1. 一共进行了4轮排序(需要进行n-1轮排序)
      1. 每一轮排序可以确定一个数的位置,比如第一轮排序确定最大的数…
      1. 当进行比较时,如果前面的数大于后面的数,就交换
      1. 每轮的比较次数在减少4->3->2->1

冒泡排序改进代码:通过swapped变量减少冒泡次数

  • 优化点:如果某一轮冒泡没有发生交换,则表示所有数据有序,可以结束外层循环
java">public class BubbleSort {public static void main(String[] args) {int[] arr ={24,69,80,57,13};System.out.println("排序前的数组:");printArray(arr);bubbleSort(arr);System.out.println("排序后的数组:");printArray(arr);}/*** 冒泡排序算法* @param arr:数组*/public static void bubbleSort(int[] arr) {int n = arr.length; // 数组长度boolean swapped;// 外层循环是控制数组循环遍历的次数:默认要循环【数组的长度-1】遍,每遍历一次子循环的比较次数就减少一次(因为每次子循环会把最大的一个元素放在数组的最后)for (int i = 0; i < n - 1; i++) {swapped = false;  // 判断数组是否有序,false表示有序(默认)// 内层循环控制每一次循环的比较和元素的交换(一轮冒泡)for (int j = 0; j < n - 1 - i; j++) {  // n-1-i表示要比较的元素的个数if (arr[j] > arr[j + 1]) { // 如果前一个元素大于后一个元素,则交换int temp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = temp;swapped = true; // 当数组元素发生交换说明数组当前不是有序的}}// 如果某一趟没有发生交换,说明数组已经有序,提前退出if (!swapped) {break;}}}// 打印数组public static void printArray(int[] arr) {for (int num : arr) {System.out.print(num + " ");}System.out.println();}}

冒泡排序最终实现

  • 优化点:用一个死循环作为外层循环,每次通过记录最后一次交换索引位置进行判断,如果在索引为0的位置,则可以结束循环。
java">public class BubbleSort {public static void main(String[] args) {int[] arr ={24,69,80,57,13};System.out.println("排序前的数组:");printArray(arr);bubbleSort(arr);System.out.println("排序后的数组:");printArray(arr);}/*** 冒泡排序算法* @param arr:数组*/public static void bubbleSort(int[] arr) {int n = a.length - 1;while (true) {int last = 0; // 表示最后一次交换索引位置for (int i = 0; i < n; i++) {System.out.println("比较次数" + i);if (a[i] > a[i + 1]) {int temp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = temp;last = i;}}n = last;System.out.println("第轮冒泡"+ Arrays.toString(a));if (n == 0) { // 表示最后一次交换索引位置break;}}}// 打印数组public static void printArray(int[] arr) {for (int num : arr) {System.out.print(num + " ");}System.out.println();}}
  • 一直冒泡,每轮冒泡时,最后一次交换的索引可以作为下一轮冒泡的比较次数,如果这个值为零,表示整个数组有序,直接退出外层循环即可。

http://www.ppmy.cn/embedded/176670.html

相关文章

tcpdump-快速查询版-常用后缀

文章目录 1. 安装Tcpdump2. Tcpdump命令语法3. 捕获特定接口的数据包 -i4. 预设捕获数据包数量 -c5. 获取详细输出 -v6. 以ASCII格式打印捕获的数据 -A7. 捕获特定源IP的数据包 src8. 捕获发往特定目标IP的数据包 dst9. 根据端口号过滤 port10. 根据协议过滤 proto11. 根据主机…

两个常用的用于读写和操作DXF文件C#库:netDxf 和 DXF.NET

netDxf 和 DXF.NET 是两个常用的C#库&#xff0c;用于读取、写入和操作DXF文件。以下是它们的详细介绍和用法示例。 1. netDxf 简介 netDxf 是一个开源的DXF文件读写库&#xff0c;支持AutoCAD DXF格式的读取和写入。它支持大多数DXF实体和对象&#xff0c;并且易于使用。 Gi…

涨薪技术|Docker容器数据管理

在生产环境中使用Docker时&#xff0c;经常需要对数据进行持久化&#xff0c;这就有点像Redis里面的持久性一样的&#xff0c;或者需要在多个容器之间在进行数据共享&#xff0c;这就是Docker中我们说的数据管理操作。 容器中管理数据主要有两种方式&#xff1a; 数据卷(Data …

RabbitMQ的高级特性介绍(二)

发送方确认 当消息的⽣产者将消息发送出去之后&#xff0c;消息到底有没有正确地到达服务器呢? 如果在消息到 达服务器之前已经丢失(比如RabbitMQ重启, 那么RabbitMQ重启期间⽣产者消息投递失败), 持久化操作也解决不了这个问题&#xff0c;因为消息根本没有到达服务器&#…

Bash 脚本基础

一、Bash 脚本基础 什么是 Bash 脚本&#xff1a;Bash 脚本是一种文本文件&#xff0c;其中包含了一系列的命令&#xff0c;这些命令可以被 Bash shell 执行。它用于自动化重复性的任务&#xff0c;提高工作效率。 Bash 脚本的基本结构&#xff1a;以 #!/bin/bash 开头&#x…

MyBatis-Plus(Ⅲ)IService详解

目录 一、逐一演示 1.save&#xff08;插入一条&#xff09; 结果 断言&#xff08;引入概念&#xff09; 2.saveBatch&#xff08;批量插入&#xff09; 结果 3.saveOrUpdateBatch&#xff08;批量插入&更新&#xff09; 结果 4.removeById&#xff08;通过id删除…

VUE2导出el-table数据为excel并且按字段分多个sheet

首先在根目录下建一个文件夹export用来存储export.js import * as XLSX from xlsxfunction autoWidthFunc(ws, data) {// 设置每列的最大宽度const colWidth data.map(row > row.map(val > {var reg new RegExp([\\u4E00-\\u9FFF], g) // 检测字符串是否包含汉字if (v…

从零到一开发一款 DeepSeek 聊天机器人

AI聊天机器人 目标设计方案系统架构技术选型功能模块 实现代码环境配置安装依赖 核心代码API 请求函数主循环函数 功能扩展1. 情感分析2. 多语言支持3. 上下文记忆4. 用户身份识别 总结附录 目标 开发一个智能聊天机器人&#xff0c;旨在为用户提供自然、流畅的对话体验。通过…