好的,我这里就以排升序、从左往右的规则进行讲解。
冒泡排序的思想就是将一个给定序列,从左端开始遍历,每两个元素一组进行比较,将较大值向后移动,重复上述操作,直到遍历到数组末尾结束,一次遍历即为一趟排序,每一趟都可以确定出一个排好序的元素。N个关键字,最多排序N趟。
刚才说的是基本思想,我们去编码实现时,可以进行优化,我能想到三个优化点。
1、N个关键字,其实排N-1次就够了,因为最后剩下的一个元素就是有序的了。
2、我这里说的是排升序的情况,那就说明每一趟排序结束都可以确定一个最大值,在下一趟排序中,可以不用包含这个最大值了,只要找出次大值即可,实现方式就是每一趟排序后,缩小下一轮待排序序列的范围。
3、在某趟排序结束后,如果没有进行过交换元素的动作,那就说明序列已经有序了,不用再排了,实现方式就是在每一躺排序前设置一个标志位,如果这趟排序结束后标志位的值没有发生更改,那就代表已经有序,直接break跳出循环或者return提前结束方法。
冒泡排序可以实现为稳定的,具体是否稳定,取决于比较规则的逻辑。
冒泡排序的最坏时间复杂度O(N^2),空间复杂度O(1)。
算法实现
1、排整数数组
/**
* 未优化版本
* 将整数数组排成升序(从左往右进行排序)
* @param arr 整数数组
*/
public static void bubbleSort(int[] arr){
for(int i = 0; i < arr.length; i++){
for(int j = 0; j < arr.length - 1; j++){
if(arr[j] > arr[j + 1]){
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
flag = false;
}
}
}
/**
* 优化版本
* 将整数数组排成升序(从左往右进行排序)
* @param arr 整数数组
*/
public static void bubbleSort(int[] arr){
for(int i = 0; i < arr.length - 1; i++){
boolean flag = true;
for(int j = 0; j < arr.length - 1 - i; j++){
if(arr[j] > arr[j + 1]){
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
flag = false;
}
}
if (flag){
break;
}
}
}
2、排对象数组
/**
* 将对象数组按指定比较器规则进行排序(从左往右进行排序)
* @param arr 对象数组
* @param comparator 比较器对象
* @param <T> 元素类型
*/
public static <T> void bubbleSort(T[] arr, Comparator<T> comparator){
for(int i = 0; i < arr.length - 1; i++){
boolean isSorted = true;
for(int j = 0; j < arr.length - 1 - i; j++){
if(comparator.compare(arr[j], arr[j + 1]) > 0){
T temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
isSorted = false;
}
}
if (isSorted){
break;
}
}
}