基本思想
冒泡排序会遍历n次要排序的数列,每次都从前往后依次比较相邻两个数的大小;如果前者比后者大,则交换它们的位置。这样,一次遍历之后,最大的元素就在数列的末尾! 采用相同的方法再次遍历,就能确定第二大的元素。重复此操作,直到整个数列都有序为止!
(第次遍历需遍历个元素)
算法性能分析
1、时间复杂度
- 最坏情况:待排序数列逆序。这样需要n-1次排序,第i趟排序需要进行次元素的比较。而且每次比较都需要移动3个元素,这种情况下,比较次数= ,移动次数=。即时间复杂度为
- 最好情况:待排序列正序。设置flag标记。第一趟排序后if语句始终不成立,flag依旧为0,从而直接跳出外层循环,程序结束。比较次数为,移动次数为0,故时间复杂度为
- 平均情况:
2、空间复杂度
额外辅助空间只有一个temp或哨兵。因此空间复杂度为
\3. 稳定性
是稳定的,但如果if语句中改用 大于(小于)等于
号,就是不稳定的,故不能改。
优化
设置一个哨兵,如果发现某一趟没有发生交换,则说明全部的排序已经完成!即可提前退出程序。
代码实现
import java.util.Arrays;
public class A {
static int[] arr = {1, 5, 3, 2, -7, 8, 0, 9, 4, 6};
static int len = 10;
public static void swap(int[] arr, int a, int b) {
int temp = arr[a];
arr[a] = arr[b];
arr[b] = temp;
}
static void bubbleSort1() {
for (int i = 0; i < len; i++) {
for (int j = 0; j < len - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
swap(arr, j, j + 1); //将数组中的两个数交换
}
}
}
}
// 冒泡排序的改进,设置一个标记,如果发现某一趟没有发生交换,则说明排序已经完成!即可提前退出
static void bubbleSort2() {
for (int i = 0; i < len; i++) {
int flag = 0;
for (int j = 0; j < len - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
flag = 1;
swap(arr, j, j + 1); //将数组中的两个数交换
}
}
if (flag == 0) {
break;
}
}
}
public static void main(String[] args) {
//bubbleSort1();
bubbleSort2();
System.out.println(Arrays.toString(arr));
}
}