
直接插入排序
发布日期:2021-05-06 23:22:42
浏览次数:21
分类:技术文章
本文共 3339 字,大约阅读时间需要 11 分钟。
1.直接插入排序
基本思想
在要排序的一组数中,假设前面(n-1) [n>=2] 个数已经是排好顺序的,现在要把第n个数插到前面的有序数中,使得这n个数也是排好顺序的。如此反复循环,直到全部排好顺序。
图像示例
算法实现
一种是从后往前插入,也是java.util.Array的实现方式
private static int[] insertSort(int[] array, int low, int high) { //从后往前插入,Array里面实现 for(int i=low+1;i<=high;i++) { //比较值 无=最后一个值不参与比较 low+1可以为low(Array实现) for (int j=i;j>low&&(array[j-1]>array[j]);j--){ //从后开始插入,每次最后的几个元素是有序的 swap(array,j,j-1); } } return array; }
一种是从前往后插入
private static int[] insertSort2(int[] array, int low, int high) {//从前往后插入 for(int i=low+1;i<=high;i++) { //第一个值不用比较,不影响 ,要=high int insertElem=array[i];// int j=i-1; // for (;j>=0;j--){// if(array[j]>insertElem) { //找到比插入值大的值将它和之后的值全部顺移往后一位(从小到大排序)// array[j+1]=array[j];// }// else {break;}// // }// array[j+1]=insertElem; //插入值位置 int j=i; //也可以j=i-1 for (;j>0;j--){ //如果是j=i-1,这里j要>=0 if(array[j-1]>insertElem) { //找到比插入值大的值将它和之后的值全部顺移往后一位(从小到大排序) array[j]=array[j-1];//[0,j]有序区? } else {break;} } array[j]=insertElem; //插入值位置 j-1为-1 ?这里的j已经在for循环里-1了 } return array; }
简单分析
时间复杂度 O(n^2)
空间复杂度O(1)
满足稳定排序
算法优化
折半插入(二分插入)
优化思路:使用二分查询减少比较次数(在数据量越大时效果越明显)
private static int[] binaryInsertSort(int[] array, int low, int high) { int i,j,index,temp; for( i=1;i<=high;i++) { index=binarySearch(array,0,i,array[i]); temp=array[i]; for(j=i;j>index;j--) { //j>index? j和index之间的数后移 array[j]=array[j-1]; } array[index]=temp; //插入 } return array; } private static int binarySearch(int[] array, int low, int high , int key) { int mid = (low+high)>>1; if(low > high) { return low; } if(array[mid]==key) { return mid; } else if(array[mid]>key) { return binarySearch(array,low,mid-1,key); } else { return binarySearch(array,mid+1,high,key); } }
2路插入
之前的折半插入是减少了比较次数,那么可不可以减少移动次数,当然可以,一种思路就是表插入,利用链表和数组之间的差异,在数组中移动需要移动其他数组元素,在链表中只需要直接插入即可
还有一种思路就是将数组当做循环数组,大于最大元素时插入到尾端,小于最小元素时插入到首端,中间元素插入到数组中间,这种实现需要一个辅助数组,最后将辅助数组里面的元素复制到原数组(再优化思路可以在插入时用二分插入,或者不用辅助数组,用中间变量,将要改变位置的元素和该位置元素交换,可以将空间复杂度降为O(1),暂时不实现了,后续再添加)
private static int[] twoInsertSort(int [] iRawBuff,int low, int high) { //21345 int fin = 0; int fir = 0; int iLenght = (high-low+1); int iTempBuff[] = new int[iLenght]; //int iRawBuff[] = new int[iLenght]; iTempBuff[0] = iRawBuff[0]; for (int i = 1; i < iLenght;i++) { if(iRawBuff[i] >= iTempBuff[fin]) { //大于当前最大值,后插 fin=(fin+1+iLenght)%iLenght; iTempBuff[fin] = iRawBuff[i]; } if(iRawBuff[i]<= iTempBuff[fir]) { //小于当前最小值,前插 fir = (fir-1+iLenght)%iLenght; iTempBuff[fir] = iRawBuff[i]; } if(iRawBuff[i] < iTempBuff[fin]&&iRawBuff[i] > iTempBuff[fir]) { //大于当前最小值,小于当前最大值,中间插 int j = fin++; while (iRawBuff[i] < iTempBuff[j]) { iTempBuff[(j+1)%iLenght] = iTempBuff[j]; j = (j-1+iLenght)%iLenght; } iTempBuff[j+1] = iRawBuff[i]; //9999? } } //导入输入到原始数组中 for (int k = 0; k < iLenght; k++) { iRawBuff[k] = iTempBuff[(fir+k)%iLenght]; } return iRawBuff; }
发表评论
最新留言
能坚持,总会有不一样的收获!
[***.219.124.196]2025年03月12日 06时57分49秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
约瑟夫环问题
2019-03-01
CF #716 (Div. 2) B. AND 0, Sum Big(思维+数学)
2019-03-01
Java 設計模式 - 建造者模式
2019-03-01
ES6 JavaScript 重新認識 Promise
2019-03-01
分享九款不同页面404源码html
2019-03-01
404页圈小猫游戏代码
2019-03-01
好看清新卡通人物404单页网站源码
2019-03-01
简洁仿t猫404页html源码
2019-03-01
Kotlin实现冒泡排序
2019-03-01
NodeJS下TypeScript环境安装
2019-03-01
汽车后市场,小程序为何独占鳌头
2019-03-01
短视频小程序,互联网新风口
2019-03-01
Mybatis-plus代码生成器模板(MySQL数据库)
2019-03-01
使用redis管理Mybatis的二级缓存
2019-03-01
使用redis管理Mybatis-Plus的二级缓存
2019-03-01
Mybatis中的SQL语句等于、不等于和模糊查询的语法
2019-03-01
使用 github 搜索
2019-03-01
java有包名的类访问没有包名的类
2019-03-01
整型关键字的散列映射
2019-03-03