面试官:请你讲一下冒泡排序

116 阅读2分钟

好的,我这里就以排升序从左往右的规则进行讲解。

冒泡排序的思想就是将一个给定序列,从左端开始遍历,每两个元素一组进行比较,将较大值向后移动,重复上述操作,直到遍历到数组末尾结束,一次遍历即为一趟排序,每一趟都可以确定出一个排好序的元素。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;
        }
    }
}