- 本文为自己的学习笔记,如果有语义错误请及时指正谢谢,
插入排序
- 插入排序是对未排序数据在有序数据中找位置插入的过程,如下图
-
排序流程
- 首先对前两个数据进行比较大小,然后确定这两个元素的顺序
- 然后将未排序的第三个元素与之前的两个数据对比,在排好序的两个数据中找到正确位置插入
- 然后就是将第四个数据与之前的排好序的三个数据对比,寻找正确位置插入
- 依照规律完成即可
-
代码分析
- 首先肯定是要有一个循环来代表整体的数据后移
- 然后还需要一个循环是需要判断未排序元素在已经排好序的数据序列中的正确位置
-
java实现代码
private static void cr(int[] arrs) { int j; for (int i = 1; i < arrs.length; i++) { j = i; while (j > 0 && arrs[j] < arrs[j-1]){ //一直判断,寻找在有序序列中的正确位置 swap(arrs,j,j-1); //数据位置互相交换的内置方法,可以利用tmp变量代替 j--; } } System.out.println(Arrays.toString(arrs)); }
Shell排序(希尔排序)
- Shell的思想是利用跳跃步数,也就是固定间隔,比较固定间隔的两个数,然后作交换,在一步步的缩小固定间隔,当固定间隔等于1的时候,数据就保持了一个基本有序的状态了,这个时排序的方法就跟插入排序差不多了,之后完成插入排序可以完成整个过程,思想也类似在插入排序上加入了跳跃步数的概念
-
排序流程
- len=6,那么他的步数的固定间隔就是len/2 = 6 / 2 = 3,所以999下标为0与下标为3的对应,然后其他数据依次对应
- 然后比较对应数据,如果小即交换
- 交换完成后,就完成了第一次排序,这时候将固定间隔调小,即再次 除以2,之前的步数间隔为3,缩小后为3/2=1,这时候代表了数据已经达到了一个基本有序,所以现在步数间隔为1,所以就是相邻的两个数字做比较交换,过程就跟插入排序类似了
- 如果在缩小间隔过程中,缩小后的步数间隔不为1,那么就继续比较交换对应下标上的数据,直到缩小后间隔为1即开始插入排序
-
代码分析
- 首先肯定要确定一个步数间隔,那么就是len /2,这也是循环的初始条件,由于间隔是不断缩减的,所以循环还需要改变一个间隔变量,因为缩减,所以这个循环中的循环变量必须保证自身要 > 0
- 上一个循环确定了len/2之后的下标增长规律后即步数间隔,那么与len/2之后的数据对应的len/2之前的数据就是len/2后的数据的下标减去间隔,然后len/2变量不断++,也就可以分别对应上len/2之前的数据
- 找到了对应数据,那么就需要用进行比较交换了
-
java代码实现
private static void shell(int[] a) { int n = a.length; //确定间隔 for (int gap = n / 2; gap > 0; gap /= 2) //len/2之后的递增1 //i就是len/2之后的元素下标 for (int i = gap; i < n; i++) //j:len/2后面元素对应len/2之前元素的下标 for (int j = i - gap; j >= 0 && a[j] > a[j + gap]; j -= gap) swap(a,j,j+gap); System.out.println(Arrays.toString(a)); }
-
另一种实现方式
private static void shell(int[] arrs) { int tmp; for (int gap = arrs.length / 2 ; gap > 0; gap /= 2) { for (int i = gap; i < arrs.length; i++) { tmp = i; while (tmp - gap > 0 && arrs[tmp] < arrs[tmp - gap]){ swap(arrs,tmp,tmp-gap); tmp -= gap; } } } System.out.println(Arrays.toString(arrs)); }
- 如果看不懂一种实现方式也不要紧,代码的实现方式是多种多样的,你可以在参考一下其他人的帖子
参考帖子