七大经典排序算法——冒泡排序

文章目录


📑冒泡排序介绍

冒泡排序是一种简单但效率较低的排序算法。它重复地比较相邻的两个元素,如果顺序不对则交换它们,直到所有元素都被比较过一次。这样每一轮比较过后,最大的元素就会"冒泡"到最后面。接着,算法将会忽略最后一个元素,重复上述比较和交换的过程,直到所有元素都按照顺序排列。

⭐ 冒泡排序算法的步骤如下:

  1. 从数组的第一个元素开始,依次比较相邻的两个元素。
  2. 如果前一个元素大于后一个元素,交换它们的位置。
  3. 继续比较下一对相邻元素,直到最后一个元素。
  4. 重复以上步骤,每一轮比较都会将最大的元素"冒泡"到最后面。
  5. 当比较结束时,此时数组已经排好序,排序结束。

动图演示如下:

🌤️代码实现

🌳C语言版

c 复制代码
// 交换函数,用于交换数组中两个元素的位置
void swap(int* arr, int i, int j) {
    int tmp = arr[i];  // 将第一个元素的值存储在临时变量 tmp 中
    arr[i] = arr[j];   // 将第二个元素的值赋给第一个元素的位置
    arr[j] = tmp;      // 将临时变量 tmp 的值赋给第二个元素的位置
}

// 冒泡排序函数,用于对数组进行排序
void bobbleSort(int* arr, int n) {
    // 外层循环控制需要遍历的轮数,共进行 n-1 次遍历
    for (int i = 0; i < n - 1; i++) {
        // 内层循环进行相邻元素的比较和交换
        // j 的范围是从 0 到 n-i-1,这样每次内层循环可以比较并将最大值移动到最后
        for (int j = 0; j < n - i - 1; j++) { // j 进循环的条件容易出错,特殊标记下
            // 如果前一个元素比后一个元素大,交换它们
            if (arr[j] > arr[j + 1]) {
                swap(arr, j, j + 1);  // 调用交换函数进行交换
            }
        }
    }
}

🌳java版

java 复制代码
// 交换函数,用于交换数组中两个元素的位置
private static void swap(int[] array, int i, int j) {
    int tmp = array[i]; // 将第一个元素的值存储在临时变量 tmp 中
    array[i] = array[j]; // 将第二个元素的值赋给第一个元素的位置
    array[j] = tmp; // 将临时变量 tmp 的值赋给第二个元素的位置
}

// 冒泡排序函数,用于对数组进行排序
public static void bubbleSort(int[] array) {
    // 外层循环控制需要遍历的轮数
    for (int i = 0; i < array.length; i++) {
        // 内层循环进行相邻元素的比较和交换
        for (int j = i + 1; j < array.length; j++) {
            // 如果前一个元素比后一个元素大,交换它们
            if (array[i] > array[j]) {
                swap(array, i, j); // 调用交换函数进行交换
            }
        }
    }
}

🌤️做个简单的优化

可以在内层循环中定义一个变量 flag:用于检测这一轮内层循环是否发生了交换。初始值设为 1。

如果在一轮内层循环中没有发生交换(flag 仍为 1),说明数组已经有序,跳出循环即可。

🌳C语言版

c 复制代码
// 交换函数,用于交换数组中两个元素的位置
void swap(int* arr, int i, int j) {
    int tmp = arr[i];  // 将第一个元素的值存储在临时变量 tmp 中
    arr[i] = arr[j];   // 将第二个元素的值赋给第一个元素的位置
    arr[j] = tmp;      // 将临时变量 tmp 的值赋给第二个元素的位置
}

// 冒泡排序函数,用于对数组进行排序
void bobbleSort(int* arr, int n) {
    // 外层循环控制需要遍历的轮数,共进行 n-1 次遍历
    for (int i = 0; i < n - 1; i++) {
        int flag = 1; // 标记用于检测这一轮是否发生了交换
        // 内层循环进行相邻元素的比较和交换
        // j 的范围是从 0 到 n-i-1,这样每次内层循环可以比较并将最大值移动到最后
        for (int j = 0; j < n - i - 1; j++) { // j 进循环的条件容易出错,特殊标记下
            // 如果前一个元素比后一个元素大,交换它们
            if (arr[j] > arr[j + 1]) {
                swap(arr, j, j + 1); // 调用交换函数进行交换
                flag = 0; // 发生交换后,将标记设置为 0
            }
        }
        // 如果没有发生交换,说明数组已经有序,提前退出排序
        if (flag) {
            break;
        }
    }
}

🌳java版

java 复制代码
// 交换函数,用于交换数组中两个元素的位置
private static void swap(int[] array, int i, int j) {
    int tmp = array[i];  // 将第一个元素的值存储在临时变量 tmp 中
    array[i] = array[j]; // 将第二个元素的值赋给第一个元素的位置
    array[j] = tmp;      // 将临时变量 tmp 的值赋给第二个元素的位置
}

public static void bubbleSort(int[] array) {
    // 外层循环控制需要遍历的轮数,共进行 array.length 次遍历
    for (int i = 0; i < array.length; i++) {
        boolean flg = true; // 标记用于检测这一轮是否发生了交换
        // 内层循环进行相邻元素的比较和交换
        // j 的范围是从 i+1 到 array.length,注意这里的起始点是 i+1
        for (int j = i + 1; j < array.length; j++) {
            // 如果前一个元素比后一个元素大,交换它们
            if (array[i] > array[j]) {
                swap(array, i, j); // 调用交换函数进行交换
                flg = false; // 发生交换后,将标记设置为 false
            }
        }
        // 如果没有发生交换,说明数组已经有序,提前退出排序
        if (flg) {
            break;
        }
    }
}

🌤️复杂度和稳定性分析

时间复杂度分析:在最坏的情况下,冒泡排序需要进行n-1轮比较,每轮比较需要进行n-i次。因此,总的比较次数为(n-1) + (n-2) + ... + 2 + 1 = n(n-1)/2,近似为O(n^2^)。

空间复杂度分析:使用了常数个变量,因此空间复杂度为O(1)

什么是稳定性?

答:稳定性指的是相同的数据所在的位置经过排序后是否发生变化。换句话说就是大小相同的两个值在排序之前和排序之后的先后顺序不变,这就是稳定的。

稳定性分析:冒泡排序将小的元素往前调或者把大的元素往后调;比较的是相邻的两个元素,交换也发生在这两个元素之间;因为相等的元素不会进行交换,所以稳定。

总结: 冒泡排序的时间复杂度为O(N^2^),空间复杂度为O(1),而且是稳定的排序。


☁️结语

请给自己些耐心,不要急于求成。
山外青山楼外楼,莫把百尺当尽头。
保持空杯心态加油努力吧!


都看到这里啦!真棒(*^▽^*)

可以给作者一个免费的赞赞吗,这将会鼓励我继续创作,谢谢大家

如有纰漏或错误,欢迎指正


相关推荐
吾日三省吾码22 分钟前
JVM 性能调优
java
stm 学习ing27 分钟前
FPGA 第十讲 避免latch的产生
c语言·开发语言·单片机·嵌入式硬件·fpga开发·fpga
LNTON羚通1 小时前
摄像机视频分析软件下载LiteAIServer视频智能分析平台玩手机打电话检测算法技术的实现
算法·目标检测·音视频·监控·视频监控
弗拉唐1 小时前
springBoot,mp,ssm整合案例
java·spring boot·mybatis
oi772 小时前
使用itextpdf进行pdf模版填充中文文本时部分字不显示问题
java·服务器
少说多做3432 小时前
Android 不同情况下使用 runOnUiThread
android·java
知兀2 小时前
Java的方法、基本和引用数据类型
java·笔记·黑马程序员
哭泣的眼泪4082 小时前
解析粗糙度仪在工业制造及材料科学和建筑工程领域的重要性
python·算法·django·virtualenv·pygame
蓝黑20203 小时前
IntelliJ IDEA常用快捷键
java·ide·intellij-idea