排序方式:
由第一个元素开始,比较相邻元素的大小,若大小顺序有误,则对调后再进行下一个元素的比较。如此扫描一次后就可以确保最后一个元素处于正确的顺序。接着再进行第二次扫描,直到完成所有元素的排序关系为止。
例:对{6,4,9,8,3}数组进行排序
原始数据:6 4 9 8 3
第一次扫描后:4 6 8 3 9
第二次扫描后:4 6 3 8 9
第三次扫描后:4 3 6 8 9
第四次扫描后:3 4 6 8 9
排序完成......
时间复杂度:
最好情况下,即数组已经有序,此时只需要进行一次扫描,此时时间复杂度为:O(n);最坏情况下,即数组元素的排序方式与要求正好相反,此时需要进行n次扫描,此时时间复杂度为:O(n^2)。
空间复杂度:
冒泡的过程只涉及相邻数据的交换操作,只需要常量级的临时空间, 是⼀个原地排序算法,空间复杂度为: O(1)。
稳定性:
相邻元素进行对调,并不更改其原本排列的顺序,所以是:稳定排序。
适用场景:
适用于数据量较小或已经有部分数据进行过排序的情况。
代码:
第一种写法:
import java.util.Arrays;
/**
*冒泡排序
* 时间复杂度:O(n^2)
* 空间复杂度:O(1)
* 稳定性:稳定
*/
public class BullSort {
public static void main(String[] args){
int[] arr = {5,2,-6,8,-3,9,7,4,1,0,-5,3,6};
System.out.println("排序前:");
System.out.println(Arrays.toString(arr));
MyBubbleSort(arr);
System.out.println("排序后:");
System.out.println(Arrays.toString(arr));
}
public static void MyBubbleSort(int[] arr){
for(int i = arr.length-1;i>=0;i--){
for (int j = 0; j < i; j++) {
if(arr[j]>arr[j+1]){
int tmp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = tmp;
}
}
}
}
}
第二种写法:
public static void MyBubbleSort(int[] arr){
for(int i = 0;i<arr.length;i++){
for (int j = 0; j < arr.length-1-i; j++) {
if(arr[j]>arr[j+1]){
int tmp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = tmp;
}
}
}
}
冒泡排序的优化:
由上面的代码可以看出,冒泡排序法有一个缺点,即不论数据是否已经有序,都需要进行n(n-1)/2次,可以对其进行优化,优化方式为在程序中加入判断来决定是否可以提前中断程序;
代码:
public static void MyBubbleSort(int[] arr){
for(int i = 0;i<arr.length;i++){
boolean flag = false;
for (int j = 0; j < arr.length-1-i; j++) {
if(arr[j]>arr[j+1]){
flag = true;
int tmp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = tmp;
}
}
//若所有元素以有序,则跳出循环
if(!flag){
break;
}
}
}