大家好我是你们的好朋友,大数据老虾。相遇是缘,既然来了就拎着小板凳坐下来一起唠会儿,如果在文中有所收获,请别忘了一键三连,动动你发财的小手,你的鼓励,是我创作的动力!废话不多说,直接 开干吧!
PS:文末干货,记得拎着小板凳离开的时候也给它顺走
座右铭:“懒”对一个人的毁灭性有多大,早起的重要性就多大。
冒泡排序是最基础的排序算法,由于它的直观性,经常被作为首个介绍的排序算法:
原理:
内循环: 使用相邻双指针 j ,j + 1从左至右开始遍历,一次比较相邻元素的大小,若左元素大于右元素则将它们进行交换,直到遍历完成时,最大元素会被交换至数组的最右边。
外循环: 不断重复内循环地操作,每轮将当前最大元素交换至 剩余未排序数组最右边, 直至所有元素都被交换正确地位置时结束。
如下图所示,首轮内循环后,数组最大元素已被交换至数组最右边,接下来,只需要完成数组剩余N - 1个元素地排序即可(设数组元素数量为N)。同理,对剩余N - 1个袁术执行内循环,可将第二大地元素交换至剩余数组地最右端,以此类推。。
如下图所示,冒泡排序地外循环共N - 1轮,每轮内循环都将当前最大元素交换至数组最右边,从而完成对整个数组地排序:
如下图所示,为示例数组 nums = [4, 1, 3, 1, 5, 2] 的 冒泡排序算法运行过程:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xWEOpCtC-1648788760110)(Images/1648786159090.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PTSMcKV0-1648788760110)(Images/1648786185927.png)][外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yDwrX6hz-1648788760110)(Images/1648786202975.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):
冒泡排序是通过不断 交换元素 实现排序(交换 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语言书籍