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

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

  • 最好情况时间复杂度: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();
    }

}

 

打印结果:

 

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

 

 


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

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值