同样的复杂度,为什么插入排序比冒泡排序更受欢迎?

前面了解了 冒泡排序 和 插入排序,时间复杂度、空间复杂度都相同:

  • 最好情况时间复杂度:O(n)
  • 最坏情况时间复杂度:O(n2)
  • 平均情况下的时间复杂度:O(n2)
  • 空间复杂度:O(1),稳定排序算法

但为什么实际开发中插入排序使用偏多呢?

原因如下:

  • 针对同一个数组,冒泡排序和插入排序,最优情况下需要交互数据的次数是一样(即原数组的逆序度一样)
  • 每次数据交换,冒泡排序的移动数据要比插入排序复杂。冒泡排序进行了 3 次赋值,插入排序进行了 1 次赋值


代码对比:

//冒泡排序
int temp = array[j + 1];
array[j+1] = array[j];
array[j] = temp;
hasSwitch = true;//有数据交换

//插入排序
if (array[j] > value) {
    array[j+1] = array[j];
} else {
    break;
}


测试代码:

package constxiong.interview.algorithm;

import java.util.Random;

/**
 * 测试冒泡排序
 * @author ConstXiong
 * @date 2020-04-10 09:36:54
 */
public class CompareBubbleAndInsertionSort {
    
    public static void main(String[] args) {
        //生成两个一样长度的随机数组
        int length = 10000;
        int[] array_1 = generateArray(length);
        int[] array_2 = new int[length]; 
        System.arraycopy(array_1, 0, array_2, 0, length);
        print(array_1);
        print(array_2);
        
        //比较冒泡排序与插入排序的耗时
        long array_1_start = System.currentTimeMillis();
        bubbleSort(array_1);
        System.out.println("bubbleSort cost time : " + (System.currentTimeMillis() - array_1_start));
        long array_2_start = System.currentTimeMillis();
        insertionSort(array_2);
        System.out.println("insertionSort cost time : " + (System.currentTimeMillis() - array_2_start));
        
        //打印排序后的两个数组,看看结果是否正确
        print(array_1);
        print(array_2);
    }
    
    /**
     * 生成随机数组
     * @param length
     * @return
     */
    private static int[] generateArray(int length) {
        Random r = new Random();
        int[] array = new int[length];
        for (int i = 0; i < array.length; i++) {
            array[i] = r.nextInt(length);
        }
        return array;
    }
    
    /**
     * 冒泡排序
     * @param array
     */
    private static void bubbleSort(int[] array) {
        for (int i = 0; i < array.length; i++) {
            //提前退出冒泡循环的标志
            boolean hasSwitch = false;
            //因为使用 j 和 j+1 的下标进行比较,所以 j 的最大值为数组长度 - 2
            for (int j = 0; j < array.length - (i+1); j++) {
                if (array[j] > array[j + 1]) {
                    int temp = array[j + 1];
                    array[j+1] = array[j];
                    array[j] = temp;
                    hasSwitch = true;//有数据交换
                }
            }
            //没有数据交换退出循环
            if (!hasSwitch) {
                break;
            }
        }
    }
    
    /**
     * 插入排序
     */
    private static void insertionSort(int[] array) {
        for (int i = 1; i < array.length; i++) {
            int j = i - 1;
            int value = array[i];
            for (; j >= 0; j--) {
                if (array[j] > value) {
                    array[j+1] = array[j];
                } else {
                    break;
                }
            }
            array[j+1] = value;
        }
    }
    
    /**
     * 打印数组
     * @param array
     */
    private static void print(int[] array) {
        for(int i : array) {
            System.out.print(i);
        }
        System.out.println();
    }

}

打印结果:

随着数组长度的提升,冒泡排序比插入排序多出的耗时也随之增多。

扫描二维码关注公众号,回复: 10834331 查看本文章

【Java面试题与答案】整理推荐

发布了562 篇原创文章 · 获赞 1543 · 访问量 165万+

猜你喜欢

转载自blog.csdn.net/meism5/article/details/105444672