同样的复杂度,为什么插入排序比冒泡排序更受欢迎?
-
最好情况时间复杂度:O(n) -
最坏情况时间复杂度:O(n2) -
平均情况下的时间复杂度:O(n2) -
空间复杂度:O(1),稳定排序算法
-
针对同一个数组,冒泡排序和插入排序,最优情况下需要交互数据的次数是一样(即原数组的逆序度一样) -
每次数据交换,冒泡排序的移动数据要比插入排序复杂。冒泡排序进行了 3 次赋值,插入排序进行了 1 次赋值
两种算法中移动数据的代码对比:
//冒泡排序
int temp = array[j + 1];
array[j+1] = array[j];
array[j] = temp;
//插入排序
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();
}
}
打印结果:
随着数组长度的提升,冒泡排序比插入排序多出的耗时也随之增多。