失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > java 实现 常见排序算法(二) 插入排序

java 实现 常见排序算法(二) 插入排序

时间:2020-11-28 08:53:01

相关推荐

java 实现 常见排序算法(二) 插入排序

大家好,我是烤鸭:

今天分享一下基础排序算法之直接插入排序。

1. 直接插入排序:

原理:假设前面的数为有序数列,然后有序数列与无序数列的每个数比较,我们可以从右向左比较

思路:从第2个数开始,和1比较。这样前2个有序。

第3个和前2个比较,这样前3个有序。(如果是最小的,则第3个元素处在第1个位置,后面的元素后移1。)

第4个和前3个比较,同上。

直到第 n 个元素 和 前 n-1 个比较。

代码实现:

/*** 直接插入排序* directInsertSort** @param array 时间复杂度,O的n^2* 直接插入排序就是我们假设前面的数为有序数列,然后有序数列与无序数列的每个数比较,我们可以从右向左比较* 当 array[i]<=array[j]=*/public void directInsertSort(int[] array) {long nowTime = System.currentTimeMillis();int tem = 0;for (int i = 1; i < array.length; i++) {int j = i - 1;tem = array[i];for (; j >= 0 && array[j] > tem; j--) {array[j + 1] = array[j];//将大于array[i]的数整体后移一单位}array[j + 1] = tem;}System.out.println("直接插入排序,花费时间(s):" + ((System.currentTimeMillis() - nowTime) / 1000.0) + "s");}

2. 折半插入排序(优化):

思路:

其实和直接插入排序是类似的,只是在遍历元素的时候采用的是二分法,直插采用的是顺序遍历。

取 temp 作为当前元素,

begin从0开始,end到数组最后一个元素。

如果temp < 中间值,begin从中间值+1继续,否则 end 变为 end - 1 继续,

begin 到 i 整体后移。

如图:(图片来源 /chengxiao/p/6103002.html)

代码实现:

/*** 折半插入排序* @param source* halfInsertSort** @param source 时间复杂度,O的n^2* 折半插入排序算法是一种稳定的排序算法,比直接插入算法明显减少了关键字之间比较的次数,* 因此速度比直接插入排序算法快,但记录移动的次数没有变,所以折半插入排序算法的时间复杂度仍然为O(n^2),* 与直接插入排序算法相同*/public static void halfInsertSort(int[] source) {long nowTime = System.currentTimeMillis();int size = source.length;for (int i = 1; i < size; i++) {// 拿出来int temp = source[i];int begin = 0; // 标记排好序的数组的头部int end = i - 1; // 标记排好序数组的尾部// 只要头部一直小于尾部,说明temp还在2个标记范围内while (begin <= end) {// 取2个标记的中间数据的值int mid = (begin + end) / 2;// 比较,若比中间值大,则范围缩小一半if (temp > source[mid]) {begin = mid + 1;// 否则,范围也是缩小一半} else {end = mid - 1;}// 循环结束时,end<begin,即i应该插入到begin所在的索引}// 从begin到i,集体后移for (int j = i; j > begin; j--) {source[j] = source[j - 1];}// 插入isource[begin] = temp;}System.out.println("折半插入排序,花费时间(s):" + ((System.currentTimeMillis() - nowTime) / 1000.0) + "s");}

3. shell排序

思路:

Shell排序也是对直接插入排序的改进。它实质上是一种分组插入方法。

下面希尔排序的步长选择都是从n/2开始,每次再减半,直到最后为1。

时间复杂度 : O(nlog2^n)

/*** 希尔排序* 针对直接插入排序的下效率问题,有人对次进行了改进与升级,这就是现在的希尔排序。* 希尔排序,也称递减增量排序算法,是插入排序的一种更高效的改进版本。希尔排序是非稳定排序算法。* 首先确定分的组数。* 然后对组中元素进行插入排序。* 然后将length/2,重复1,2步,直到length=0为止。* @param arr*/public void shellSort(int [] arr){long nowTime = System.currentTimeMillis();int len=arr.length;//单独把数组长度拿出来,提高效率while(len!=0){len=len/2;for(int i=0;i<len;i++){//分组for(int j=i+len;j<arr.length;j+=len){//元素从第二个开始int k=j-len;//k为有序序列最后一位的位数int temp=arr[j];//要插入的元素/*for(;k>=0&&temp<arr[k];k-=len){arr[k+len]=arr[k];}*/while(k>=0&&temp<arr[k]){//从后往前遍历arr[k+len]=arr[k];k-=len;//向后移动len位}arr[k+len]=temp;}}}System.out.println("希尔排序,花费时间(s):" + ((System.currentTimeMillis() - nowTime) / 1000.0) + "s");}

耗时对比:

10W 条随机 数据 运行如图:

可以看出希尔排序时间明显(比直插排序和折半排序)缩短。折半排序和直插排序时间差不多。

50W 条随机 数据 运行如图:

可以看出希尔排序时间明显(比直插排序和折半排序)缩短。折半排序和直插排序时间差不多。

100W 条随机 数据 运行如图:

可以看出希尔排序时间明显(比直插排序和折半排序)缩短。折半排序比直插排序耗时更多。

总结:

直接插入排序写法比较简单,平均时间复杂度为:O(n^2)。

折半插入排序,平均时间复杂度为:O(n^2)。

希尔排序,平均时间复杂度为:O(nlog2^n)。

各种排序方法比较:

更多排序算法:

冒泡排序 :/Angry_Mills/article/details/81057900

如果觉得《java 实现 常见排序算法(二) 插入排序》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。