通俗理解插入排序(直接插入排序,折半插入排序,希尔排序)
来源:互联网 发布:制作淘宝优惠券网站 编辑:程序博客网 时间:2024/05/16 08:58
直接插入排序
直接插入排序就是将待排序的值,逐一按元素的大小插入前面的有序序列
例如对-23,45,2,-45,9,5,3,65,-24进行直接插入排序,我们可以看成将45,2,-45,9,5,3,65,-24逐步插入-23的序列
package sort;public class Demo6 { public static void main(String[] args) { int[] num = new int[]{-23,45,2,-45,9,5,3,65,-24}; sort(num); for (int i = 0; i < num.length; i++) { System.out.print(num[i]+" "); } } public static void sort(int[] data){ int tmp;//暂时保存待插入的值 //从第2个开始,进行n-1的插入操作 for (int i = 1; i < data.length; i++) { //若待插入的值比前面有序序列的最大值都大,则说明现在就是有序的 if(data[i]<data[i-1]){ tmp = data[i]; int j = i-1; for (; j >=0&&data[j]>tmp; j--) { data[j+1] = data[j];//把数据往后移动 } data[j+1] = tmp;//退出循环时候,j指向的数值比tmp小,或者j<0 } } }}
折半插入排序
折半插入排序是对直接插入排序的一种改进,直接插入排序中0到i-1有序的,折半插入排序就是用折半查找迅速找到需要插入的地方,而不用从i-1开始逐一向前比较。
使用折半查找查找3应该插入的位置,
1. low=0 hight=6 mid=(low+hight)/2=3
因为data[3]<=data[7],说明应该插入的位置在4-6之间
2. low=mid+1=3+1=4 hight=6 mid=(low+hight)/2=5
因为data[5]>data[7]说明应该插入的位置在4到5间
3 low=4 hight=mid-1=5 mid=(4+5)/2=4
因为data[4]>data[7]所以插入的位置是4,但是此时折半查找并没有结束
4 low=4 hight=mid-1=3 因为此时low>hight所以折半折半查找结束
low的位置便是应该插入的位置(该位置满足data[low]>待插入的值,data[hight]<=待插入的值,或者hight为-1,也就是插入的位置为0)
5 将low到i-1的数字都往后移动腾出low的位置将插入值插入,注意备份i位置的值避免被覆盖后找不回待插入值。
package sort;public class Demo7 { public static void main(String[] args) { int[] data = new int[]{-23,45,2,-45,9,5,3,65,-24}; sort(data); for (int i = 0; i < data.length; i++) { System.out.print(data[i]+" "); } } public static void sort(int[] data){ int low,hight,mid; int tmp;//备份存储待插入的值 for (int i = 1; i < data.length; i++) { if(data[i]<data[i-1]){ tmp = data[i]; low = 0; hight = i-1; while(low<=hight){ mid = (low+hight)/2; if(data[mid]<=tmp){ //当中间值小于等于待插入的值,搜索[mid+1,hight]区间 low = mid +1; }else{ hight = mid - 1; //当中间值小于等于待插入的值,搜索[low,mid-1]区间 } } //将[low,i-1]区间的值后移动 for (int j = i-1; j >= low; j--) { data[j+1] = data[j]; } //待插入的值插入 data[low] =tmp; } } }}
希尔排序(Shell排序)
Shell排序是对直接插入排序的改进,它通过加大插入排序中元素之间的间隔,并在这些有间隔的元素进行插入排序,使得数据项跨度移动,不用一步一步往前比较和移动。
Shell排序算法的关键就在于确定h序列的值,h就是间隔多少,序列最小值为1(这时就是直接插入排序),它们存在h=3*h+1的关系。当对一个数列进行Shell排序时,h的值为多少开始比较合适?h刚好大于数列长度除于3。
int h=1;while(h<=arrayLength/3){ h = 3*h+1;}//得到的h的值就是Shell排序的增量
得到了Shell排序的增量h序列值后,就从第h个后面数字开始对前面间隔h的值进行插入排序。
例如对-23,45,2,-45,9,5,3,65,-24进行Shell排序
1.长度为9,则可以计算出增量为4
2.从第4个后面数字(这里就是9)开始对前面间隔4的值进行插入排序
package sort;public class Demo5 { public static void main(String[] args) { int[] num = new int[]{-23,45,2,-45,9,5,3,65,-24}; sort(num); } public static void sort(int[] data){ int h = 1;//增量最小为1 int tmp;//存储待插入的值 while(h<=data.length/3){ //计算Shell的最大增量 h = h * 3 + 1; } while(h>=1){ //从第h后面的数字开始对前面的间隔为h的数字进行插入排序,也就是从第h+1个开始,下标为h for(int i = h; i<data.length; i++){ tmp = data[i]; if(data[i-h]>tmp){ int j = i-h; //对前面的间隔为h的数字进行插入排序,,,当为1时就是直接插入排序了 for (; j>=0&&data[j]>tmp; j=j-h) { data[j+h] = data[j];//数据往后移动,间隔为h } data[j+h] = tmp;//这里加上h是因为循环最后还减多了一个h } } h = (h-1)/3;//重新计算h的值,寻找小一点的增量 //打印出来看看,每一趟的Shell排序 for (int j = 0; j < data.length; j++) { System.out.print(data[j]+" "); } System.out.println(); } }}
三种插入排序的时间复杂度和空间复杂度
个人博客:http://www.javaknowledge.cn/?p=21
- 通俗理解插入排序(直接插入排序,折半插入排序,希尔排序)
- 插入排序(希尔排序、直接插入、折半插入排序)
- 插入排序:直接插入排序,折半查找排序,希尔排序
- 排序算法--直接插入排序、折半插入排序、希尔排序
- java实现排序算法之插入排序(直接插入排序,折半插入排序,希尔排序)
- 排序算法——插入排序(直接插入排序、折半插入排序、希尔排序)
- 插入排序(直接插入,折半插入,希尔)
- 直接插入排序 && 折半插入排序 && 希尔排序
- 直接插入排序,折半插入排序,希尔排序
- 直接插入排序、折半插入排序、希尔排序
- java数据结构之插入排序(直接插入排序、折半插入排序、希尔排序)
- 插入排序:直接插入, 折半插入,希尔插入
- 插入排序(直接插入排序,折半插入排序,2路插入排序,希尔排序)
- 插入排序(直接插入排序,折半插入排序,2路插入排序,希尔排序)
- 排序算法(堆排序,直接插入排序,折半插入排序,希尔排序)
- 数据结构-插入排序(直接插入排序+折半插入排序)
- 冒泡排序和插入排序(直接插入、折半插入、希尔排序)(殷人昆版)
- 直接插入排序,二分(折半)插入排序,希尔插入排序
- 2119数据结构实验之链表四:有序链表的归并
- 创建JQuery检测元素是否含有指定属性hasAttr的原型
- Spring:源码解读(IOC体系结构)
- 让我们如此享受的慢性毒药
- Spring Factory Bean
- 通俗理解插入排序(直接插入排序,折半插入排序,希尔排序)
- nyoj973天下第一
- JDK1.8更新的有关接口的内容,接口里面可以有方法体,lamdba语法
- Django笔记---用户注册和登录验证(2)--数据库储存
- 通用的查询接口DynamicObjectFactory
- php数组操作方法 (函数)
- Vmware安装ubuntu编译android源码详细过程
- 机器学习个人资料整理
- JAVA实践优化Prim最小生成树算法