美文网首页
算法-排序-冒泡排序和插入排序的对比

算法-排序-冒泡排序和插入排序的对比

作者: TioSun | 来源:发表于2020-07-27 21:37 被阅读0次

什么是冒泡排序

冒泡排序的特点是每次都是相邻的两个数进行比较,是一个比较简单的排序算法其实现如下

package sort;

/**
 * @author TioSun
 * 冒泡排序
 */
public class BubbleSort {


    /**
     * 冒泡排序
     * @param a 待排序数组
     * @param n 数组大小
     */
    public void sort(int[] a, int n) {
        if (n <= 1) return;

        for (int i = 0; i < n; ++i) {
            // 提前退出冒泡循环的标志位
            boolean flag = false;
            for (int j = 0; j < n - i - 1; ++j) {
                // 相邻的两位数进行比较
                if (a[j] > a[j+1]) {
                    // 交换
                    int tmp = a[j];
                    a[j] = a[j+1];
                    a[j+1] = tmp;
                    // 表示本次循环有发生交换动作
                    flag = true;      
                }
            }
            // 如果某次循环没有发生交换,则说明数组有序,可以提前退出循环
            if (!flag) {
                break;
            }
        }
    }
}

冒泡排序是稳定排序吗?

从代码中我们可以看出,相邻的两个元素相等时,我们是不做交换动作的,所以冒泡排序是稳定排序

冒泡排序是原地排序吗?

从代码中我们可以看到,我们只用了常量级的额外空间,所以是原地排序

冒泡排序的时间复杂度

最好的情况是待排序数组已经是有序的,这个时候冒泡排序只需要遍历一次数组即可完成排序,所以最好情况的时间复杂度是O(n),最坏情况是数组正好和排序结果相逆,这是需要的时间复杂度是O(n2)。那么平均时间复杂度是多少?这里大家可以去了解下有序度的相关知识,篇幅原因暂时不讲了。可以给出的是平均时间复杂度还是O(n2)。

什么是插入排序

插入排序的思维来自于向有序数组中插入一个数据的动作。对于待排序数组,我们将其划分成两块区域,有序区和无序区。初始有序区只有数组的第一个元素,通过向后遍历,不断向有序区插入数据从而完成排序动作。

package sort;

/**
 * @author TioSun
 * 插入排序
 */
public class InsertionSort {

    /**
     * 插入排序
     *
     * @param a 待排序数据
     * @param n 数据量
     */
    public void sort(int[] a, int n) {
        // 无需排序
        if (n <= 1) {
            return;
        }

        for (int i = 1; i < n; ++i) {
            // 需要插入的数据
            int value = a[i];
            int j = i;
            // 查找插入的位置,因为i是待插入数据的下标,所以i-1的位置是有序区的终端(0是起始端)
            for (; j > 0; --j) {
                // 将待插入数据和左边的数据比较
                if (a[j-1] > value) {
                    //右移数据以腾出位置给待插入数据
                    a[j] = a[j-1];
                } else {
                    break;
                }
            }
            // 插入数据
            a[j] = value;
        }
    }

}

插入排序是稳定排序吗

当数值相同时,我们并不会把后面的数据插入到前面去,所以插入排序是稳定排序。

插入排序是原地排序吗

插入排序只使用了常数级的额外空间,所以是原地排序。

插入排序的时间复杂度

和分析冒泡排序的方式相同,插入排序的最好时间复杂度是O(n)(待排序数组已符合要排序顺序),最坏时间复杂度是O(n2)(待排序数组和要排序顺序相逆),平均时间复杂度是O(n2)。

为什么我们更常用插入排序

从上面的分析来看,不管是稳定性、空间复杂度还是时间复杂度,冒泡排序和插入排序的对比都是一致的,那为什么在两种排序算法选择时我们更倾向于插入排序呢?
我们可以对比下两种算法的核心部分

// 冒泡排序
if (a[j] > a[j+1]) {
 // 交换
 int tmp = a[j];
 a[j] = a[j+1];
 a[j+1] = tmp;
 // 表示本次循环有发生交换动作
 flag = true;
}

// 插入排序
if (a[j-1] > value) {
   //右移数据以腾出位置给待插入数据
  a[j] = a[j-1];
} else {
     break;
}

可以比较清楚的对比出,冒泡排序一次交换需要进行三次赋值动作,而插入排序只需要进行一次赋值动作。可能会有同学认为这差异很大吗?其实差异很大的,我设了两万个随机数,分别用冒泡排序和插入排序对其进行排序,其时间差异如下图:


image.png

能明显看出数据量大的时候,插入排序所消耗的时间更少

相关文章

  • 冒泡排序、插入排序、选择排序

    三种算法对比: 冒泡排序 插入排序 选择排序 测试 提升 冒泡排序和插入排序的时间复杂度都是 O(n2),都是原地...

  • python 冒泡排序和选择排序算法

    插入排序算法 冒泡排序算法

  • 图形化排序算法比较:快速排序、插入排序、选择排序、冒泡排序

    图形化排序算法比较:快速排序、插入排序、选择排序、冒泡排序 图形化排序算法比较:快速排序、插入排序、选择排序、冒泡排序

  • 排序一:冒泡、插入、选择

    文章结构 概述 冒泡排序 插入排序 选择排序 1. 概述 常见的排序算法有:冒泡排序、插入排序、选择排序、归并排序...

  • 简单排序

    排序是基础的算法问题,常见的排序有插入排序、冒泡排序、快速排序等,它们分别有不同的计算复杂度。插入排序和冒泡排序的...

  • 基础排序算法总结

    排序算法分为内部排序和外部排序,而我们经常说的基础排序算法,都是内部排序算法。包括冒泡排序,选择排序,插入排序,快...

  • 算法

    1.常用的八个基本排序算法 -前言:希尔排序和直接插入排序属于插入排序算法,简单选择排序和堆排序属于选择排序,冒泡...

  • 详解排序算法--希尔排序

    希尔排序 希尔排序的由来是根据插入排序的。读者若不了解插入排序,可以参考笔者的详解排序算法--插入排序和冒泡排序....

  • Chapter 2 Foundation of Algorith

    Chapter 2 插入排序 线性查找 选择算法 归并排序算法 二分查找算法 冒泡排序 插入排序 循环不...

  • 常用的排序算法

    常用的排序算法 常用的排序算法插入排序折半插入排序shell 排序冒泡排序选择排序快速排序基数排序归并排序堆排序K...

网友评论

      本文标题:算法-排序-冒泡排序和插入排序的对比

      本文链接:https://www.haomeiwen.com/subject/ivetrktx.html