直接插入排序(Straight Insertion Sorting)的基本思想:在要排序的一组数中,假设前面(n-1) [n>=2] 个数已经是排好顺序的,现在要把第n个数插到前面的有序数中,使得这n个数也是排好顺序的。如此反复循环,直到全部排好顺序。

复杂度:时间复杂度  O(n2) ,空间复杂度O(1)

稳定性: 插入排序是稳定的,排序前后两个相等元素相对次序不变(能保证排序前2个相等的数其在序列的前后位置顺序和排序后它们两个的前后位置顺序相同。在简单形式化一下,如果Ai = Aj, Ai原来在位置前,排序后Ai还是要在Aj位置前。)

结构的复杂性及适用情况:是一种简单的排序方法,不仅适用于顺序存储结构(数组),而且适用于链接存储结构,不过在链接存储结构上进行直接插入排序时,不用移动元素的位置,而是修改相应的指针。

哨兵的作用

 算法中引进的附加记录R[0]称监视哨或哨兵(Sentinel)。

  哨兵有两个作用:

① 进人查找(插入位置)循环之前,它保存了R[i]的副本,使不致于因记录后移而丢失R[i]的内容;

② 它的主要作用是:在查找循环中"监视"下标变量j是否越界。一旦越界(即j=0),因为R[0].key和自己比较,循环判定条件不成立使得查找循环结束,从而避免了在该循环内的每一次均要检测j是否越界(即省略了循环判定条件"j>=1")。

注意:

① 实际上,一切为简化边界条件而引入的附加结点(元素)均可称为哨兵。

【例】单链表中的头结点实际上是一个哨兵

② 引入哨兵后使得测试查找循环条件的时间大约减少了一半,所以对于记录数较大的文件节约的时间就相当可观。对于类似于排序这样使用频率非常高的算法,要尽可能地减少其运行时间。所以不能把上述算法中的哨兵视为雕虫小技,而应该深刻理解并掌握这种技巧。

 package lsg.ap.insert;
 /**
  * 插入排序算法
  *
  */
 public class InsertSort
 {
     public static void straightInsertionSort(int []array)
     {
         int sentinel , j;
         for (int i = 1; i < array.length; i++)
         {
             j = i - 1;
             sentinel = array[i];//哨兵位,作为单独的存储空间用于依次取出每一个i对应的
                                //元素,插入到前面已经排好顺序的 元素中 ,见VisualGo上的演示
                                //词句实际上是把j+1位置处的元素提前取出来了,这样往后移位就可
                                //以无数据丢失了
             while (j >= 0 && sentinel < array[j]) //升序或者降序直接修改此处的"<"为">"即可
             {
                 array[j+1] = array[j];//将大于sentinel的值整体后移一个单位
                                       //但与Sentinel的值已经排号顺序了,放心后移即可
                 j--;
             }
             array[j+1] = sentinel; //最后j指到该插入的位置,已经正好空出位置了,直接插入即可
         }
     }
     /**
      *
      * 输出相应数组的结果
      * @param array
      */
     private static void printArray(int[] array)
     {
        for(int value:array)
        {
            System.out.print(" "+value+" ");

        }
        System.out.println();
     }
     public static void main(String[] args)
     {
         // TODO Auto-generated method stub
         int[] array=new int[]{8,3,2,1,7,4,6,5};

          System.out.println("排序前数组元素为:");
          printArray(array);
          long dateStart=System.nanoTime();
          straightInsertionSort(array);
          long dateEnd=  System.nanoTime();
          long totalTime=dateEnd-dateStart;
          System.out.println("插入排序的时间复杂度为:");
          System.out.println(totalTime+"纳秒");
          System.out.println("排序后数组元素为:");
          printArray(array);
     }

 }

Java基础(47):插入排序的Java封装(含原理,可运行,哨兵位的理解见VisualGo上面的动态分析)的更多相关文章

  1. Java基础-面向对象第一特性之封装(Encapsulation)

    Java基础-面向对象第一特性之封装(Encapsulation) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.理解什么是面向过程和面向对象 面向过程与面向对象都是我们编程中 ...

  2. Java基础系列1:Java基本类型与封装类型

    Java基础系列1:Java基本类型与封装类型 当初学习计算机的时候,教科书中对程序的定义是:程序=数据结构+算法,Java基础系列第一篇就聊聊Java中的数据类型. 本篇聊Java数据类型主要包括两 ...

  3. 【Java基础】11、java方法中只有值传递,没有引用传递

    public class Example { String testString = new String("good"); char[] testCharArray = {'a' ...

  4. 【Java基础】4、java中的内部类

    内部类的分类:常规内部类.静态内部类.私有内部类.局部内部类.匿名内部类. 实例1:常规内部类 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 2 ...

  5. JAVA基础——面向对象三大特性:封装、继承、多态

    JAVA面向对象三大特性详解 一.封装 1.概念: 将类的某些信息隐藏在类内部,不允许外部程序直接访问,而是通过该类提供的方法来实现对隐藏信息的操作和访问. 2.好处: 只能通过规定的方法访问数据. ...

  6. Java基础语法05-面向对象-封装-包-构造器-初始化

    封装 面向对象三大特性:封装.继承.多态 封装的好处 1.调用者:方便使用/简化使用 2.设计者:安全,可控 隐藏对象内部的复杂性,只对外公开简单的接口.便于外界调用,从而提高系统的可扩展性.可维护性 ...

  7. 夯实Java基础系列5:Java文件和Java包结构

    目录 Java中的包概念 包的作用 package 的目录结构 设置 CLASSPATH 系统变量 常用jar包 java软件包的类型 dt.jar rt.jar *.java文件的奥秘 *.Java ...

  8. Java基础学习笔记八 Java基础语法之接口和多态

    接口 接口概念 接口是功能的集合,同样可看做是一种数据类型,是比抽象类更为抽象的”类”.接口只描述所应该具备的方法,并没有具体实现,具体的实现由接口的实现类(相当于接口的子类)来完成.这样将功能的定义 ...

  9. 夯实Java基础系列1:Java面向对象三大特性(基础篇)

    本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 [https://github.com/h2pl/Java-Tutorial](https: ...

随机推荐

  1. .Net 2.0自带的Json序列化、反序列化方法

    public class JsonUtil    {        public static T DeserializeObject<T>(string json)        {   ...

  2. nRF51822之模拟IIC

    使用的工程为是基于sdk10工程 在将以nRF51_SDK_10.0.0_dc26b5e\examples\peripheral\twi_sensor作为模版 修改代码main.c #include ...

  3. wpf前端设计

    http://www.cnblogs.com/w-wanglei/archive/2016/03/14/5274298.html#_nav_0

  4. 用CSS为表格添加边框

    格式: <style type="text/css"> table tr td,th {border:1px solid #000;} </style>

  5. 获得输入框的文本document.getElementById('id').value;

    <input id="demo" type="text" value="" > x=document.getElementByI ...

  6. backgroundworker的应用

    一种情况是当凭证界面加载时,因为加载项比较多,辅助项的处理,可以应用backgroundworker启用另一线程进行加载,不影响当前界面的显示,提高响应速度. 情况2 是月末结转余额时,因为用时间较长 ...

  7. CodeTimer

    using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using S ...

  8. Java学习-020-Properties 判断是否存在对应的 key 项

    在日常的脚本编写过程中,通常会判断配置文件中是否存在对应的配置项,以判断是否执行相应的业务逻辑. 小二上码...若有不足之处,敬请大神指正,不胜感激! 判断是否存在 key 项(配置项)的方法源码如下 ...

  9. Flash的坑之ExternalInterface.call只返回null值的解决办法

    flash坑太多了,要确保能有效的使用ExternalInterface.call调用js的话,需要两个条件: 1.allowScriptAccess="always" 2.id= ...

  10. 针对应用程序池“xxxxxx”的模板永久性缓存初始化失败,解决方法

    日志名称:          Application 来源:            Active Server Pages 日期:            2014-11-22 9:09:39 事件 I ...