【详解排序算法】冒泡排序

大家好🙌我是你们的好朋友,大数据老虾😀。相遇是缘,既然来了就拎着小板凳坐下来一起唠会儿😎,如果在文中有所收获,请别忘了一键三连,动动你发财的小手👍,你的鼓励,是我创作的动力😁!废话不多说,直接😎 开干吧!

PS:文末干货,记得拎着小板凳离开的时候也给它顺走 🤣
座右铭:“懒”对一个人的毁灭性有多大,早起的重要性就多大

【排序算法】冒泡排序

算法解析

冒泡排序是最基础的排序算法,由于它的直观性,经常被作为首个介绍的排序算法:

原理:

  • 内循环: 使用相邻双指针 j ,j + 1从左至右开始遍历,一次比较相邻元素的大小,若左元素大于右元素则将它们进行交换,直到遍历完成时,最大元素会被交换至数组的最右边。

  • 外循环: 不断重复内循环地操作,每轮将当前最大元素交换至 剩余未排序数组最右边, 直至所有元素都被交换正确地位置时结束。

如下图所示,首轮内循环后,数组最大元素已被交换至数组最右边,接下来,只需要完成数组剩余N - 1个元素地排序即可(设数组元素数量为N)。同理,对剩余N - 1个袁术执行内循环,可将第二大地元素交换至剩余数组地最右端,以此类推。。

流程图进行解析

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

如下图所示,冒泡排序地外循环共N - 1轮,每轮内循环都将当前最大元素交换至数组最右边,从而完成对整个数组地排序:

image.png

案列详解

如下图所示,为示例数组 nums = [4, 1, 3, 1, 5, 2] 的 冒泡排序算法运行过程:

image.png

image.png

image.png

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xWEOpCtC-1648788760110)(Images/1648786159090.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PTSMcKV0-1648788760110)(Images/1648786185927.png)][外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yDwrX6hz-1648788760110)(Images/1648786202975.png)]

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

算法实现

// java code
void bubbleSort(int[] nums) {
    int N = nums.length;
    for (int i = 0; i < N - 1; i++) {          // 外循环
        for (int j = 0; j < N - i - 1; j++) {  // 内循环
            if (nums[j] > nums[j + 1]) {
                // 交换 nums[j], nums[j + 1]
                int tmp = nums[j];
                nums[j] = nums[j + 1];
                nums[j + 1] = tmp;
            }
        }
    }
}
# python code
def bubble_sort(nums):
    N = len(nums)
    for i in range(N - 1):           # 外循环
        for j in range(N - i - 1):   # 内循环
            if nums[j] > nums[j + 1]:
                # 交换 nums[j], nums[j + 1]
                nums[j], nums[j + 1] = nums[j + 1], nums[j]

算法特性

时间复杂度 O(N^2):

  • 最佳Ω(N) : 普通冒泡排序的时间复杂度恒为 O(N^2),对于近似排序数组,通过加入标志位可实现提前返回(详情请见下文)。
  • 平均与最差 O(N^2): 「外循环」共 N - 1轮,使用 O(N)时间;每轮「内循环」分别遍历 N - 1 , N - 2, ⋯ , 2 , 1次,平均 2N次,使用 O( 2N)=O(N) 时间;因此,总体时间复杂度为 O(N^2)。
  • 空间复杂度 O(1): 只需原地交换元素,使用常数大小的额外空间。

冒泡排序是通过不断 交换元素 实现排序(交换 2 个元素需要 3 次赋值操作),因此速度较慢;

  • 原地: 指针变量仅使用常数大小额外空间,空间复杂度为 O(1);

  • 稳定: 元素值相同时不交换,因此不会改变相同元素的相对位置;

  • 自适应: 通过增加一个标志位 flag ,若某轮内循环未执行任何交换操作时,说明已经完成排序,因此直接返回。此优化使冒泡排序的最优时间复杂度达到 O(N)(当输入数组已排序时;

算法优化

普通冒泡排序的时间复杂度恒为 O(N^2),与输入数组的元素分布无关。

优化方案:

1、通过增加一个标志位flag,若在某轮内循环中未执行任何交换操作,则说数组已经完成排序,可直接返回结果。

2、优化后的冒泡排序的最差和平均时间复杂度未为(N^2)

3、在输入数组已排序时,达到 最佳时间复杂度Ω(N) 。

// java code
void bubbleSort(int[] nums) {
    int N = nums.length;
    for (int i = 0; i < N - 1; i++) {
        boolean flag = false; // 初始化标志位
        for (int j = 0; j < N - i - 1; j++) {
            if (nums[j] > nums[j + 1]) {
                int tmp = nums[j];
                nums[j] = nums[j + 1];
                nums[j + 1] = tmp;
                flag = true;  // 记录交换元素
            }
        }
        if (!flag) break;     // 内循环未交换任何元素,则跳出
    }
}
# python code
def bubble_sort(nums):
    N = len(nums)
    for i in range(N - 1):
        flag = False         #  初始化标志位
        for j in range(N - i - 1):
            if nums[j] > nums[j + 1]:
                nums[j], nums[j + 1] = nums[j + 1], nums[j]
                flag = True  # 记录交换元素
        if not flag: break   # 内循环未交换任何元素,则跳出

文末彩蛋🤩

🚗🤩😉💖🌹👀✨给各位朋友安利一下平时收集的各种学习资料!!!有需要的朋友点击一下传送门,自行领取。程序员经典名言:“收藏了就等于学会啦”。 做人也要像蜡烛一样,在有限的一生中有一分热发一份光,给人以光明,给人以温暖!
图灵程序丛书300+
Linux实战100讲
Linux书籍
计算机基础硬核总结
计算机基础相关书籍
操作系统硬核总结
Java自学宝典
Java学习资料
Java硬核资料
Java面试必备
Java面试深度剖析
阿里巴巴Java开发手册
MySQL入门资料
MySQL进阶资料
深入浅出的SQL
Go语言书籍

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值