【排序基础】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) { //区分 哪部分是已经排序好的 / ...
随机推荐
- JavaScript:常用的一些数组遍历的方法
常用的一些遍历数组的方法: <!DOCTYPE html> <html> <head> <meta charset="utf-8"> ...
- JavaScript:浏览器的本地存储
cookie.localStorage.sessionStorage的使用 <!DOCTYPE html> <html lang="en"> <hea ...
- EditPlus各个版本的注册码,亲测可用
原文链接:https://www.cnblogs.com/shihaiming/p/6422441.html EditPlus4注册码 注册名:host1991 序列号:14F50-CD5C8- ...
- Redis存储对象(序列化和反序列化)
代码以及实例: package com.hp.test; import redis.clients.jedis.Jedis; import java.io.*; public class Test3 ...
- DVWA各等级命令注入漏洞
漏洞描述 在web程序中,因为业务功能需求要通过web前端传递参数到后台服务器上执行,由于开发人员没有对输入进行严格过滤,导致攻击者可以构造一些额外的"带有非法目的的"命令,欺骗后 ...
- oracle 11g调优常用语句
1.查询表的基数及选择性 select a.column_name, b.num_rows, a.num_distinct cardinality, round( ...
- Unity 黑暗之光 笔记 第三章
第三章 角色控制 1.创建游戏运行场景并导入素材资源 2.创建和管理标签 1 //const 表明这个是一个共有的不可变的变量 2 public const string ground = &qu ...
- 记一次HBase的NotServingRegionException问题
1. 问题 在hbase测试集群上,访问一些hbase表,均报类似下面的错误:region不可用 Wed Oct 28 14:00:56 CST 2020, RpcRetryingCaller{glo ...
- 03-flask-视图函数基础
代码 from flask import Flask, request, url_for, jsonify, redirect # 创建Flask对象 app = Flask(__name__) @a ...
- Python高级语法-多继承MRO相关-多继承顺序(4.5.1)
@ 目录 1.说明 2.代码 关于作者 1.说明 使用类的魔法方法__mro__ 可以查看他的父类调用顺序 还有调用父类的构造方法的时候,使用super调用,里面有C3算法支持,不会重复调用相同的祖先 ...