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


📑冒泡排序介绍

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

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

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

动图演示如下:
在这里插入图片描述

🌤️代码实现

🌳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版

// 交换函数,用于交换数组中两个元素的位置
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语言版

// 交换函数,用于交换数组中两个元素的位置
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版


// 交换函数,用于交换数组中两个元素的位置
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(n2)。

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

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

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

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


☁️结语

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


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

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

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


  • 8
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值