冒泡排序(Bubble Sort)
视频讲解链接:【十大排序算法】用可视化动画讲冒泡排序
1、介绍
对待排序序列从前向后开始,依次比较两个相邻元素的值,若发现逆序则交换,使值较大的元素逐渐从前向后移动,就像水底下的气泡一样逐渐向上冒。
2、算法步骤
1、进行n-1轮比较。
2、每轮比较从第一个元素开始,比较相邻元素的值,若发现逆序则交换。
3、代码实现
package sort;
import java.util.Arrays;
public class BubbleSort {
public static void main(String[] args) {
int arr[] = { 44,82,37,59,5,36};
// 冒泡排序
bubbleSort(arr);
System.out.println("排序后");
System.out.println(Arrays.toString(arr));
}
// 冒泡排序
public static void bubbleSort(int[] arr) {
int temp; // 临时变量
int indexMax = arr.length - 1; // 数组下标最大值
// roundCount:轮数,front:前面的数
for (int roundCount = 0; roundCount < indexMax; roundCount++) {
for (int front = 0; front < indexMax - roundCount; front++) {
// 如果前面的数比后面的数大,则交换
if (arr[front] > arr[front + 1]) {
temp = arr[front];
arr[front] = arr[front + 1];
arr[front + 1] = temp;
}
}
}
}
// 优化代码
public static void bubbleSort2(int[] arr) {
int temp; // 临时变量
boolean flag = false; // 一轮比较中是否发生交换
int indexMax = arr.length - 1; // 数组下标最大值
for (int roundCount = 0; roundCount < indexMax; roundCount++) {
for (int front = 0; front < indexMax - roundCount; front++) {
// 如果前面的数比后面的数大,则交换
if (arr[front] > arr[front + 1]) {
flag = true;
temp = arr[front];
arr[front] = arr[front + 1];
arr[front + 1] = temp;
}
}
if (!flag) {
// 在一轮排序中,一次交换都没有发生过,说明已经排好序,跳出循环,排序结束
break;
} else {
// 此时flag=true,重新赋值,准备下一轮比较
flag = false;
}
}
}
}
4、时空复杂度
最好的时间复杂度为O(n):若待排序列是正序的,一趟扫描即可完成排序。
最坏时间复杂度为O(n2):若待排序列是反序的,需要进行n-1趟排序。每趟排序要进行 n-roundCount 次比较。
在进行冒泡排序的时候,假设数组中存在n个元素:
第1轮排序: n个元素比较n-1次
第2轮排序:n-1个元素比较n-2次
第3轮排序: n-2个元素比较n-3次
…
第n-2轮排序:3个元素比较n-(n-2)=2次
第n-1轮排序:2个元素比较n-(n-1)=1次
那么将上面比较的次数相加:(n-1)+(n-2)+(n-3)+ …+ 3+2+1 = n*(n-1)/2= (n2-n)/2,最高次幂项是n2/2,不看系数是n2。
平均时间复杂度为O(n2)
空间复杂度为O(1):仅仅使用了一个临时变量的空间。
5、稳定性
冒泡排序是一种稳定的排序算法
在冒泡排序进行相邻元素比较的时候,如果相邻的两个元素大小是相等的,那么这两个元素并不会进行互换。并且,冒泡排序算法每一轮比较都是从数组的最开始,一步一步向后进行比较,所以并不会出现两个相同值的元素之间互换的情况。
6、算法优化
用flag变量标记每轮比较中是否发生交换,如果没有交换则说明已经排好序了,就不用再继续比较了。
7、结束语
微信扫描小程序码体验冒泡排序动画演示: