直接插入排序(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. ubuntu 64bit arm-linux-gcc: No such file or directory 解决

    通过下面这个解决 ubuntu 64bit  arm-linux-gcc: No such file or directory 安装 sudo apt-get install lsb-core解决 h ...

  2. windows SVN搭建

    Subversion是优秀的版本控制工具,其具体的的优点和详细介绍,这里就不再多说. 首先来下载和搭建SVN服务器. 现在Subversion已经迁移到apache网站上了,下载地址: http:// ...

  3. 一个例子深入理解ClassLoader

    文件类加载器,该加载器重载了loadClass方法,逻辑是只读取文件来加载类,不委托给父类加载器进行加载 package com.ydd.study.hello.classloader; import ...

  4. bootstrap响应式布局简单实例

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8&quo ...

  5. tomecat 配置修改 及启动配置

    a.如果tomcat是以bat方式启动的,则如下设置: 修改TOMCAT_HOME/bin/catalina.sh 在“echo "Using CATALINA_BASE: $CATALIN ...

  6. iptables常用操作

    1.iptables服务重启 service iptables restart 2.保存iptables规则 iptables-save > ~/iptables.save 3.恢复iptabl ...

  7. Speed-BI云平台正在公测中,欢迎大家体验!

    Speed-BI云平台正在公测中,欢迎大家体验.访问地址:http://speedbi.cn 支持IE(建议IE8以上),Edge,Chrome,Firefox,Safari等任意浏览器,以及采用这几 ...

  8. SpringMVC Map Model ModelMap 和 ModelAndView

    代码: package com.gaussic.controller; import com.gaussic.model.AccountModel; import org.springframewor ...

  9. Json.Net Demo2

    新建一个空的Web项目,名称JsonServer,该网页实现Ajax数据请求和响应. 添加Newtonsoft.Json.dll的Dll引用,添加JQuery API文件,目录结构如下: 新建一个Pe ...

  10. javascript原生dom操作方法

    一.节点层次属性 考虑空白符的相关层次关系属性: 1.childNodes属性 包含 2.parentNode属性 3.previouseSibling属性和nextSibling属性 4.first ...