详解冒泡排序算法
基本思想
冒泡排序的基本思想是:
通过对待排序的序列从前向后依次比较相邻元素的值,如果发现逆序则交换。
逆序的含义:如果想把序列从小到大排序,那么两个数中前面的比后面的大就是逆序。
若需求是将序列从小到大排序,那么每一趟比较都会把值较大的逐渐从前面移动到后面。
就像水底的泡泡一样:
(如下图,图片来源于网络)
例子
给定一个数组如下:
[ 5 , 8 , -2 , 20 -6 ]
定义两个变量 i 和 j,初始状态 i 存第一个元素的索引,j存i代表元素的下一个元素的索引;
如下图:
第一趟排序
(1) 5 < 8不用发生交换
然后 i ,j 均向后移动;
(2) 8 > -2 需要发生交换
然后 i ,j 均向后移动;
(3) 8 < 20 不需要发生交换
然后 i ,j 均向后移动;
(4) 20 > -6 需要发生交换
此时 j已经不能向后移动,第一趟排序结束,将当前最大的元素 20 移动到了最后的位置。
第二趟排序
将 i ,j重新赋值如下:
第三趟排序
将 i ,j重新赋值如下:
第四趟排序
将 i ,j重新赋值如下:
四个数组均到达该到的位置,排序完毕。
由此可见,每一趟排序都会减少比较次数。
会 有数组长度-1趟排序。
代码
使用双重循环来完成:
int temp;//用于交换的临时变量
for(int i=0;i<arr.length - 1;i++){
for(int j = 0;j<arr.length - 1 - i ; j++){
if(arr[j] > arr[j + 1]){
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
优化
如果一趟排序都没有发生交换,表示已经有序了,没必要进行接下来的排序了。
可以定义一个 flag ,初始值为false,如果发生交换,就赋值为true,否则一直是false直接退出循环。
代码如下:
import java.lang.reflect.Array;
import java.util.Arrays;
public class Solution {
public static void main(String[] args) {
bubbleSort(new int[]{5,8,-2,20,-6});
}
public static void bubbleSort(int[] arr) {
int temp;//用于交换的临时变量
boolean flag = false;//表示是否进行交换
for(int i=0;i<arr.length - 1;i++){
for(int j = 0;j<arr.length - 1 - i ; j++){
if(arr[j] > arr[j + 1]){
flag = true;
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
if(!flag){
break;
}else{
flag = false;//将flag重新置为false
}
}
System.out.println(Arrays.toString(arr));
}
}
时间复杂度
如果原数组有序,则遍历一遍就可以,最好的时间复杂度是
$O(n)$;
如果原数组倒序,则比较次数是:
n-1 + n-2 + … + 2 + 1 = $\frac{n(n-1)}{2}$ = $O(n^2)$;
所以冒泡排序的时间复杂度是$O(n^2)$。
稳定性
冒泡排序就是把逆序的元素进行交换,每次都是相邻的两个元素比较,交换也发生在这两个元素之间。所以,如果两个元素相等,是不会再交换的;如果两个相等的元素没有相邻,那么即使通过前面的两两交换把两个相邻起来,这时候也不会交换,所以相同元素的前后顺序并没有改变,所以冒泡排序是一种稳定排序算法。
总结
冒泡排序的思想是通过对待排序的序列从前向后依次比较相邻元素的值,如果发现逆序则交换。
优化方法是,若一趟排序中没有发生交换则退出循环,已经有序。
冒泡排序的时间复杂度是$O(n^2)$,是稳定的排序算法。
欢迎关注
欢迎大家的关注
扫描下方的二维码关注我的微信公众号:code随笔
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· NetPad:一个.NET开源、跨平台的C#编辑器
· PowerShell开发游戏 · 打蜜蜂
· 凌晨三点救火实录:Java内存泄漏的七个神坑,你至少踩过三个!