直接插入排序(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. epoll 应用

    /*  * test_bittube.cpp  *  *  Created on: 2015年7月13日  *      Author: ting.guit  */ #include <bind ...

  2. Ngrok 内网穿透利器

    Ngrok是什么 Ngrok 是一个反向代理,通过在公共的端点和本地运行的 Web 服务器之间建立一个安全的通道.Ngrok 可捕获和分析所有通道上的流量,便于后期分析和重放 为什么要使用Ngrok ...

  3. MySQL安装图解教程

    安装文件存放路径:不能有中文和空格! 校验 1 安装MySQL 2 校验MySQL 登录MySQL:mysql -uroot -p123 退出MySQL:exit | quit 查看数据库:show ...

  4. nrf51822-配对绑定实现过程

    关于配对绑定的一些原理内容这里不再重复介绍,看之前的几篇文档,静态密码,动态密码,连接时触发配对就可以了. 配对绑定的内容可能比较难懂,升入的学习需要去看规范,将前面的几篇相关文档看一遍实验一边再去看 ...

  5. AppDelegate

    一.基础知识 1) main.m指定了程序的入口点 UIApplicationMain(argc, argv,nil,NSStringFromClass([StartingPointAppDelega ...

  6. TCP粘包

    一.通信协议TCP/UDP: TCP(transport control protocol,传输控制协议)是面向连接的,面向流的,提供高可靠性服务.客户端和服务器端都要有一一成对的socket, 因此 ...

  7. Mac下安装和配置mongoDB

    mac下的mongodb下载安装比较简单,主要有两种方式,一种是下载压缩包解压,另一种是通过npm或者homebrew命令安装,这里就不赘述了, 复杂的在于mongodb运行环境的配置(若未配置运行环 ...

  8. Wall---hdu1348(求凸包周长 模板)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1348 求凸包周长+2*PI*L: #include <stdio.h> #include ...

  9. Asp.net MVC 批量删除数据

    ProductList视图 <div class="mid"> <div id="editInfo"> @using (Html.Beg ...

  10. linux bq20z75 驱动

    新的项目中使用到了电池.电池的guage使用TI的bq20z75.kernel的驱动中已经有bq20z75的驱动,只要稍加修改就可以使用. 参考链接 http://www.ti.com/lit/er/ ...