【排序基础】5、插入排序法 - Insertion Sort
插入排序法 - 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的更多相关文章
- 算法Sedgewick第四版-第1章基础-2.1Elementary Sortss-002插入排序法(Insertion sort)
一.介绍 1.时间和空间复杂度 运行过程 2.特点: (1)对于已排序或接近排好的数据,速度很快 (2)对于部分排好序的输入,速度快 二.代码 package algorithms.elementar ...
- 【DS】排序算法之插入排序(Insertion Sort)
一.算法思想 一般来说,插入排序都采用in-place在数组上实现.具体算法描述如下:1)从第一个元素开始,该元素可以认为已经被排序2)取出下一个元素,在已经排序的元素序列中从后向前扫描3)如果该元素 ...
- 《算法4》2.1 - 插入排序算法(Insertion Sort), Python实现
排序算法列表电梯: 选择排序算法:详见 Selection Sort 插入排序算法(Insertion Sort):非常适用于小数组和部分排序好的数组,是应用比较多的算法.详见本文 插入排序算法的语言 ...
- 插入排序—直接插入排序(Straight Insertion Sort)
基本思想: 将一个记录插入到已排序好的有序表中,从而得到一个新,记录数增1的有序表.即:先将序列的第1个记录看成是一个有序的子序列,然后从第2个记录逐个进行插插入到已入,直至整个序列有序为止. 要点: ...
- 直接插入排序(Straight Insertion Sort)
body, table{font-family: 微软雅黑; font-size: 13.5pt} table{border-collapse: collapse; border: solid gra ...
- 【算法】插入排序(Insertion Sort)
(PS:内容参考MIT算法导论) 插入排序(Insertion Sort): 适用于数目较少的元素排序 伪代码(Pseudocode): 例子(Example): 符号(notation): 时间复杂 ...
- 【算法】插入排序(Insertion Sort)(三)
插入排序(Insertion Sort) 插入排序(Insertion-Sort)的算法描述是一种简单直观的排序算法.它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相 ...
- 插入排序(Insertion Sort)
这是排序算法中最常见的排序方法,也是初学者使用最多的.有时候我们在生活中也会不自觉地用到插入排序,例如: 给手里的牌排序 这是最常见的例子之一,我们通常从纸牌的一边开始看,找到一张位置不正确的,把它拿 ...
- php 四种基础算法 ---- 插入排序法
3.插入排序法 插入排序法思路:将要排序的元素插入到已经 假定排序号的数组的指定位置. 代码: function insert_sort($arr) { //区分 哪部分是已经排序好的 / ...
随机推荐
- Jwt令牌创建
添加依赖 <dependencies> <!-- jwt --> <dependency> <groupId>io.jsonwebtoken</g ...
- Hadoop使用实例 词频统计和气象分析
一.词频统计 下载喜欢的电子书或大量文本数据,并保存在本地文本文件中 编写map与reduce函数 本地测试map与reduce 将文本数据上传至HDFS上 用hadoop streaming提交任务 ...
- PHP与Mysql之间的纠缠(超详细)
目录 第一章 PHP操作mysql数据库 index.html代码 connect.php代码如下: list.php代码如下: 第二章 PHP 会话管理和控制 一.php 会话控制 之 PHP中的C ...
- MyBatis详细源码解析(上篇)
前言 我会一步一步带你剖析MyBatis这个经典的半ORM框架的源码! 我是使用Spring Boot + MyBatis的方式进行测试,但并未进行整合,还是使用最原始的方式. 项目结构 导入依赖: ...
- C# 海量数据瞬间插入到数据库的方法
C# 海量数据瞬间插入到数据库的方法 当我们在数据库中进行大量的数据追加时,是不是经常因为数据量过大而苦恼呢?而所谓的海量数据,一般也是上万级的数据,比如我们要添加一百万条数据,应该如何提高它的效率呢 ...
- Java进阶:基于TCP通信的网络实时聊天室
目录 开门见山 一.数据结构Map 二.保证线程安全 三.群聊核心方法 四.聊天室具体设计 0.用户登录服务器 1.查看当前上线用户 2.群聊 3.私信 4.退出当前聊天状态 5.离线 6.查看帮助 ...
- Java学习_反射
什么是反射? 反射就是Reflection,Java的反射是指程序在运行期可以拿到一个对象的所有信息. 反射是为了解决在运行期,对某个实例一无所知的情况下,如何调用其方法. JAVA反射机制是在运行状 ...
- Mac 下 IDEA 启动慢的问题
转自: http://blog.csdn.net/KingBoyWorld/article/details/73440717 从控制台来看,每次都会连接本地地址(127.0.0.1),问题可能就出在这 ...
- 开发规范(三)数据库 By 阿里
建表规约 索引规约 SQL语句 ORM映射
- element-ui 表单 v-if 不能验证问题
element-ui 表单v-if 很多人会遇到无法验证的问题,网上很多是在el-form-item标签前加一个div然后把v-if拿到div上去像这样 <div v-if="addc ...