插入排序法 - Insertion Sort

简单记录-bobo老师的玩转算法系列–玩转算法 -排序基础

插入排序 Insertion Sort

比较 插入

插入排序设计思想

插入排序将数列划分为“已排序的”和“未排序的”两部分,每次从“未排序的”元素中选择一个插入到“已排序的”元素中的正确位置,如此迭代直到全部元素有序。

一般将将数组的第一个数认为是有序数组,第一个数不需要考虑 已经排好了,不需要插入到前面去。从后往前扫描该有序数组,把数组中其余n-1个数,根据数值的大小,插入到有序数组中,直至数组中的所有数为有序数组为止。n个元素的话就需要进行n-1趟排序!比较 插入。

例如:1 2 3 4进行从大到小的排序

第一趟

1 2 3 4

从后往前扫描有序数组,将第二个数字2和有序数组中的1进行比较,2大于1,所以将1后移一个位置,正好此时也是扫描完该有序数组中所以的数,所以结果是将2插入到1的前面,得到新的序列2,1;

2 1 3 4

第二趟

2 1 3 4

3开始,3比1大,1后移一个位置,就是这两个交换一下位置

2 3 1 4

3比2大,2后移一个位置。

3 2 1 4

第三趟

3 2 1 4

4开始,4比1大,1后移一个位置

3 2 4 1

4比2大,2后移一个位置

3 4 2 1

4比3大,3后移,比完了

4 3 2 1

插入排序代码实现

InsertionSort

package algo;

import java.util.*;

public class InsertionSort{

    // 我们的算法类不允许产生任何实例
private InsertionSort(){} public static void sort(Comparable[] arr){ int n = arr.length;
for (int i = 0; i < n; i++) { // 寻找元素arr[i]合适的插入位置 // 写法1
// 比较 当前与它的前一个 小于的话就交换 大的话就中止这一趟
// 插入排序比选择 第二个循环比较 提前中止 理论上插入比选择快点 但是...实际上为什么更慢呢?下一节介绍可以改进吧 // for( int j = i ; j > 0 ; j -- )
// if( arr[j].compareTo( arr[j-1] ) < 0 )
// swap( arr, j , j-1 );
// else
// break; // 写法2
//同时满足两个 j > 0 小于的话就一直交换 一旦大于就中止 下一个数进行比较
for( int j = i; j > 0 && arr[j].compareTo(arr[j-1]) < 0 ; j--)
swap(arr, j, j-1); }
} private static void swap(Object[] arr, int i, int j) {
Object t = arr[i];
arr[i] = arr[j];
arr[j] = t;
} // 测试InsertionSort
public static void main(String[] args) { int N = 200;
Integer[] arr = SortTestHelper.generateRandomArray(N, 0, 10000);
SortTestHelper.testSort("algo.InsertionSort", arr); return;
}
}

SortTestHelper.java

package algo;

import java.lang.reflect.Method;
import java.lang.Class; public class SortTestHelper { // SortTestHelper不允许产生任何实例
private SortTestHelper(){} // 生成有n个元素的随机数组,每个元素的随机范围为[rangeL, rangeR]
public static Integer[] generateRandomArray(int n, int rangeL, int rangeR) { assert rangeL <= rangeR; Integer[] arr = new Integer[n]; for (int i = 0; i < n; i++)
arr[i] = new Integer((int)(Math.random() * (rangeR - rangeL + 1) + rangeL));
return arr;
} // 打印arr数组的所有内容
public static void printArray(Object[] arr) { for (int i = 0; i < arr.length; i++){
System.out.print( arr[i] );
System.out.print( ' ' );
}
System.out.println(); return;
} // 判断arr数组是否有序
public static boolean isSorted(Comparable[] arr){ for( int i = 0 ; i < arr.length - 1 ; i ++ )
if( arr[i].compareTo(arr[i+1]) > 0 )
return false;
return true;
} // 测试sortClassName所对应的排序算法排序arr数组所得到结果的正确性和算法运行时间
public static void testSort(String sortClassName, Comparable[] arr){ // 通过Java的反射机制,通过排序的类名,运行排序函数
try{
// 通过sortClassName获得排序函数的Class对象
Class sortClass = Class.forName(sortClassName);
// 通过排序函数的Class对象获得排序方法
Method sortMethod = sortClass.getMethod("sort",new Class[]{Comparable[].class});
// 排序参数只有一个,是可比较数组arr
Object[] params = new Object[]{arr}; long startTime = System.currentTimeMillis();
// 调用排序函数
sortMethod.invoke(null,params);
long endTime = System.currentTimeMillis(); assert isSorted( arr ); System.out.println( sortClass.getSimpleName()+ " : " + (endTime-startTime) + "ms" );
}
catch(Exception e){
e.printStackTrace();
}
}
}

Result 测试 InsertionSort

D:\Environments\jdk-11.0.2\bin\java.exe -javaagent:D:\Java\ideaIU-2019.2.win\lib\idea_rt.jar=7391:D:\Java\ideaIU-2019.2.win\bin -Dfile.encoding=UTF-8 -classpath D:\IdeaProjects\imooc\Play-with-Algorithms\02-Sorting-Basic\out\production\05-Insertion-Sort algo.InsertionSort
InsertionSort : 2ms
48 68 73 256 393 415 512 520 521 549 558 613 618 650 707 709 720 755 813 830 841 853 856 894 1017 1061 1092 1199 1212 1227 1374 1421 1454 1535 1552 1584 1601 1617 1652 1758 1907 1979 1998 2081 2103 2107 2157 2246 2271 2274 2312 2319 2365 2418 2449 2509 2565 2569 2629 2668 2741 2793 2927 2950 2956 3105 3140 3166 3209 3287 3364 3403 3407 3427 3469 3573 3645 3835 3887 3902 3919 4045 4071 4122 4225 4300 4355 4364 4378 4412 4505 4516 4523 4533 4546 4636 4650 4678 4776 4780 4821 4911 5010 5174 5204 5220 5231 5426 5473 5484 5645 5827 5884 5887 5902 5939 6012 6031 6063 6174 6210 6334 6337 6358 6358 6367 6405 6412 6448 6639 6678 6838 6991 7002 7148 7189 7327 7357 7400 7429 7519 7522 7559 7634 7733 7841 7945 7960 8013 8116 8139 8193 8203 8214 8222 8234 8243 8248 8258 8273 8309 8357 8452 8569 8586 8662 8687 8740 8842 8853 8863 8891 8907 8930 8950 9011 9086 9148 9239 9251 9286 9321 9346 9392 9434 9491 9518 9537 9589 9601 9675 9766 9801 9825 9837 9882 9883 9884 9915 9962 Process finished with exit code 0

操作:插入排序与选择排序的比较

Main

package algo;

import java.util.Arrays;

public class Main {

    // 比较SelectionSort和InsertionSort两种排序算法的性能效率
// 此时,插入排序比选择排序性能略低
public static void main(String[] args) { int N = 200000;//20万个数排序
System.out.println("Test for random array, size = " + N + " , random range [0, " + N + "]"); Integer[] arr1 = SortTestHelper.generateRandomArray(N, 0, N);
Integer[] arr2 = Arrays.copyOf(arr1, arr1.length);//拷贝数组 SortTestHelper.testSort("algo.SelectionSort", arr1);
SortTestHelper.testSort("algo.InsertionSort", arr2); return;
}
}

选择 插入排序 性能不行 数据集合一大点 就很慢很慢了

比较 交换 次数太多了

Result

D:\Environments\jdk-11.0.2\bin\java.exe -javaagent:D:\Java\ideaIU-2019.2.win\lib\idea_rt.jar=7405:D:\Java\ideaIU-2019.2.win\bin -Dfile.encoding=UTF-8 -classpath D:\IdeaProjects\imooc\Play-with-Algorithms\02-Sorting-Basic\out\production\05-Insertion-Sort algo.Main
Test for random array, size = 200000 , random range [0, 200000]
SelectionSort : 87513ms
InsertionSort : 335960ms Process finished with exit code 0

【排序基础】5、插入排序法 - Insertion Sort的更多相关文章

  1. 算法Sedgewick第四版-第1章基础-2.1Elementary Sortss-002插入排序法(Insertion sort)

    一.介绍 1.时间和空间复杂度 运行过程 2.特点: (1)对于已排序或接近排好的数据,速度很快 (2)对于部分排好序的输入,速度快 二.代码 package algorithms.elementar ...

  2. 【DS】排序算法之插入排序(Insertion Sort)

    一.算法思想 一般来说,插入排序都采用in-place在数组上实现.具体算法描述如下:1)从第一个元素开始,该元素可以认为已经被排序2)取出下一个元素,在已经排序的元素序列中从后向前扫描3)如果该元素 ...

  3. 《算法4》2.1 - 插入排序算法(Insertion Sort), Python实现

    排序算法列表电梯: 选择排序算法:详见 Selection Sort 插入排序算法(Insertion Sort):非常适用于小数组和部分排序好的数组,是应用比较多的算法.详见本文 插入排序算法的语言 ...

  4. 插入排序—直接插入排序(Straight Insertion Sort)

    基本思想: 将一个记录插入到已排序好的有序表中,从而得到一个新,记录数增1的有序表.即:先将序列的第1个记录看成是一个有序的子序列,然后从第2个记录逐个进行插插入到已入,直至整个序列有序为止. 要点: ...

  5. 直接插入排序(Straight Insertion Sort)

    body, table{font-family: 微软雅黑; font-size: 13.5pt} table{border-collapse: collapse; border: solid gra ...

  6. 【算法】插入排序(Insertion Sort)

    (PS:内容参考MIT算法导论) 插入排序(Insertion Sort): 适用于数目较少的元素排序 伪代码(Pseudocode): 例子(Example): 符号(notation): 时间复杂 ...

  7. 【算法】插入排序(Insertion Sort)(三)

    插入排序(Insertion Sort) 插入排序(Insertion-Sort)的算法描述是一种简单直观的排序算法.它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相 ...

  8. 插入排序(Insertion Sort)

    这是排序算法中最常见的排序方法,也是初学者使用最多的.有时候我们在生活中也会不自觉地用到插入排序,例如: 给手里的牌排序 这是最常见的例子之一,我们通常从纸牌的一边开始看,找到一张位置不正确的,把它拿 ...

  9. php 四种基础算法 ---- 插入排序法

    3.插入排序法 插入排序法思路:将要排序的元素插入到已经 假定排序号的数组的指定位置. 代码: function insert_sort($arr) {    //区分 哪部分是已经排序好的    / ...

随机推荐

  1. 最详细Python批量字典暴力破解zip密码

    工具破解 前两天在网上下来了一波项目案例,结果全是加密的压缩包,于是去网上找了一个压缩包破解的工具 苦于工具破解太慢,一个压缩包要好久,解压了三个之后就放弃了,准备另寻他法 密码字典 巧的是破解的三个 ...

  2. Java8新特性探索之新日期时间库

    一.为什么引入新的日期时间库 Java对日期,日历及时间的处理一直以来都饱受诟病,尤其是它决定将java.util.Date定义为可修改的以及将SimpleDateFormat实现成非线程安全的. 关 ...

  3. 【Django admin 中文配置】

    打开settings.py文件,找到语言编码.时区的设置项,将内容改为如下: [其中 zh-Hans是简体中文 zh-Hant是繁体中文] LANGUAGE_CODE = 'zh-Hans' # LA ...

  4. vue检查用户名是否重复

    前端函数如下,js方法代码无需更改,前端代码逻辑在components\common\lab_header.vue 只需要修改components\axios_api\http.js中调用的后端地址 ...

  5. GC agent的安装和卸载

    一.GC agent安装 下面介绍GC agent的push和pull两种安装方法 1.push(推送)安装GC agent方法 1).打开EMGC home page:https://even.or ...

  6. 精尽Spring MVC源码分析 - HandlerMapping 组件(二)之 HandlerInterceptor 拦截器

    该系列文档是本人在学习 Spring MVC 的源码过程中总结下来的,可能对读者不太友好,请结合我的源码注释 Spring MVC 源码分析 GitHub 地址 进行阅读 Spring 版本:5.2. ...

  7. IO流(03)--序列化流、打印流

    序列化流 Java提供了一种对象序列化的机制,用一个字节序列可以表示一个对象,该字节序列包含该对象的数据.对象的类型和对象中存储的属性等信息.字节序列写入到文件中后,就相当于在文件中保存了一个对象信息 ...

  8. Struts2-059 漏洞复现

    0x00 漏洞简介 Apache Struts框架, 会对某些特定的标签的属性值,比如id属性进行二次解析,所以攻击者可以传递将在呈现标签属性时再次解析的OGNL表达式,造成OGNL表达式注入.从而可 ...

  9. centos 7 让脚本开机运行

    按照网上搜索的文章指导,有三种方式可以实现,个人觉得比较简单的是修改/etc/rc.d/rc.local,添加要开机执行的命令. 修改后,重启,发现要运行的服务没有启动. 搜索发现下面这篇博客解释了原 ...

  10. Liunx运维(三)-文件过滤及内容编辑处理

    文档目录: 一.cat:合并文件或查看文件内容 二.tac:反向显示文件内容 三.more:分页显示文件内容 四.less:分页显示文件内容 五.head:显示文件头部内容 六.tail:显示文件尾部 ...