美文网首页java进阶干货技术干货Android开发经验谈
java 实现排序算法之「插入排序」

java 实现排序算法之「插入排序」

作者: ikook | 来源:发表于2017-12-23 12:48 被阅读268次

java 实现排序算法系列

这是 Java 实现排序算法的第三篇文章——插入排序算法。插入排序可以说成是「一类」简单的排序算法,因为插入排序可以有变种,比如二分查找插入排序算法,本文讲述的是直接插入排序。

如文中出现错误,请在公众号「ikook」聊天窗口留言,十分感谢。

插入排序

插入排序「Insertion Sort」是一种简单直观的排序算法。它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。

来看一下插入排序算法的思路:

  • 将需排序的数据分成已排序和未排序两部分,从第一个元素开始,并将该元素看做已排序。

  • 取得下一个元素,即第二个元素,在已排序的序列中由后向前扫描,找出合适的位置将该元素插入。

  • 重复上述步骤,直到最后一个元素被插入到已排序序列中。

  • 排序完成。

使用插入排序为一列数字进行排序的过程示意图(来自维基百科):

<center>



</center>

插入排序算法示意图(来自维基百科):

<center>



</center>

代码实现

从上面可以看到,算法思路非常简单,但是代码就不那么简单易写了。算法本身是没有问题的,之所以不易写我觉得是由于编程语言的问题。这里我们使用 Java 来实现,那就拿 Java 来讲。

在上述思路中我们可以提出几个问题,先来看下。首先,我们该如何判断合适的位置?边界条件该怎么处理?在数组中插入元素,必然会移动数据,如何控制数据的移动?

为了解决这些问题,我们可以在算法思路的第二步做手脚,将第二步细化。我们不在已排序的序列起始位置开始比较,从已排序序列的尾部开始逆序比较,只要比待插入的数据大,那就向后移动,直到不大于该数据,此时空出来的位置就放入待插入数据。

上代码:

private static void insertionSort(int[] arr){
      for (int i=1; i<arr.length; i++){
          int value = arr[i];
          int position=i;
          while (position>0 && arr[position-1]>value){
              arr[position] = arr[position-1];
              position--;
          }
          arr[position] = value;
      }
}

如果在代码的理解上遇到困难,可以利用 IDE 的调试功能来学习。如下图(IntelliJ IDEA):

<center>



</center>

算法复杂度

从上述内容容易看出,无论输入的数据怎样,插入排序算法总会进行 n-1 次排序。

由于每个元素插入点的不确定性,该算法复杂度并不是一定的。假设我们要将 n 个元素的序列升序排序,这时存在最好情况和最坏情况。

最好情况就是,序列已经是升序排列了(即数据本身的顺序和我们需要的顺序相同)。此时,需要进行的比较操作需(n-1)次即可,时间复杂度为 O(n)。

最坏情况很显然,序列为逆序排列时,即降序排序时为最坏。此时,需要进行的比较共有 1/2n(n-1) 次,时间复杂度为 O(n^2)。

平均来说,插入排序算法复杂度为 O(n^2)。插入排序的赋值操作是比较操作的次数加上(n-1)次。

空间复杂度,插入排序所有的数据移动均在内部进行,唯一的开销是我们使用了一个临时变量,则空间复杂度为 O(1)。

插入排序算法分析

算法稳定性:
拿本文中的例子来讲,只需要找到需插入元素的位置即可,并不需要交换,则直接插入排序是稳定排序算法。

适用场景:
从算法复杂度可以看出,该排序算法不适合数据较大的情况,数量级小于千时,插入排序是一个不错的选择。在 STL 的 sort 算法和 stdlib 的 qsort 算法中,都将插入排序作为快速排序的补充,用于少量数据的排序。

其他

关于插入排序算法的变种大家有兴趣的自己 Google 一下,本文只讲述了基本的直接插入排序。插入排序的变种大概有这几种:二分查找插入排序、2 - 路插入排序、表插入排序。二分查找插入排序有的文献叫做折半插入排序,2 - 路插入排序和表插入排序可以参考《数据结构》(严蔚敏、吴伟民著)一书。

完。

相关阅读:
Java 实现「冒泡排序」
Java 实现「选择排序」

PS:如果你觉得本文对你有一点帮助,点赞、转发,不胜感激。

相关文章

  • 数据结构&算法(一)

    一、Java实现快速排序算法 二、Java实现折半插入排序算法 三、Java实现冒泡排序算法

  • java 实现排序算法之「插入排序」

    java 实现排序算法系列 这是 Java 实现排序算法的第三篇文章——插入排序算法。插入排序可以说成是「一类」简...

  • 算法-插入排序

    算 法:插入排序算法时间复杂度: 插入排序算法描述 插入排序伪代码 插入排序实现 插入排序算法概述 插入排...

  • java快速学习排序---插入排序

    1.java实现插入排序 (1)、图解插入排序 (2)、插入排序的思想 (3)、插入排序的代码实现

  • 五种常见排序算法实现(Java)

    Java-五种排序算法实现 前言及准备 这篇我们会介绍比较简单的五种排序算法:插入排序、冒泡排序、快速排序、选择排...

  • 排序算法的实现

    用java对常用内部排序算法的实现。 对冒泡排序,简单选择排序,直接插入排序,希尔排序,归并排序的简单实现(缺少快...

  • JS实现排序算法

    原文:常见排序算法之JavaScript实现 - 知乎 目录 冒泡排序 选择排序 插入排序 合并排序 快速排序 1...

  • 十大经典排序算法(java实现)

    前言 本文我们将以java代码实现十大经典排序算法,包括冒泡排序、选择排序、插入排序、希尔排序、归并排序、快速排序...

  • 常见排序的java实现

    常见排序的java实现 常见排序java实现 插入排序(二分插入排序) 希尔排序 快速排序(三数中值快排) 冒泡排...

  • 插入排序算法实现

    排序算法是最常见,最基础的算法,作者文集中记录了两种排序算法(插入排序,归并排序) 插入排序算法实现很简单直接,附...

网友评论

    本文标题:java 实现排序算法之「插入排序」

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