java实现直接插入排序

来源:互联网 发布:linux的常用命令 编辑:程序博客网 时间:2024/06/01 09:26

数据结构与算法复习
同样学习过C语言版,这里用java实现直接插入排序


常用的插入排序两种:直接插入排序和希尔排序,本文介绍的就是直接插入排序




排序算法思想


依次把待排序中的数插入到一个有序序列中。

简单的实现方式就是,待排序数组第一个数是一个有序数组,那么依次从第二个数开始,把剩余的待排序序列从有序序列尾部开始依次比较,然后找到要插入的位置,然后新的序列又是一个有序序列。 那么每次插入一个数是一定有数需要移动的,这里有两个移动时机:

1.待排序数 <= 有序序列中的数 ,则有序序列中的数右移一位空出位置。如此往复

2.一直比较直到找到了插入的位置后,再把需要右移的数整体右移。(实际上就是把找位置与移位分开而已)


图示

百度的图,感谢贡献者


java代码实现


        public static void directSort(int[] arr) {int waitInsert;//等待插入的数int i,j;//i表示当前待插入数下标;j表示本次被比较的有序数位置for(i = 1; i < arr.length; i++) {waitInsert = arr[i];//得到本轮待插入的数j = i - 1;//比较位置初始化,也就是有序序列的最后一个位置,从后往前//若大于或等于等待插入的数值大小,则该数右移,然后进行下一次比较while(j > -1 && arr[j] >= waitInsert) {arr[j + 1] = arr[j];j--;}//插入的位置一定是上一次比较的数的位置,也就是j+1的位置。(注意到j--的时机即可理解)arr[j + 1] = waitInsert;}}

测试代码:

public static void main(String[] args) {int arrLength = 10;//测试数组的长度/* * 获得随机arrLength个数的数组  */int[] arr = new int[arrLength];for(int i = 0;i < arrLength;i++){arr[i] = (int) (Math.random() * arrLength);}//排序前的输出for(int a:arr){System.out.print(a+" ");}System.out.println();directSort(arr);//排序后的输出for(int a:arr){System.out.print(a+" ");}}

随机产生的10个数作为样本,三组测试结果:

2 3 5 1 8 4 8 9 2 1 1 1 2 2 3 4 5 8 8 95 3 4 0 7 1 6 2 9 4 0 1 2 3 4 4 5 6 7 9 7 3 1 1 9 7 6 6 7 5 1 1 3 5 6 6 7 7 7 9



时间复杂度

最好的情况:原始数据都排好了序。这时内存层while的次数每次都为0。外层for每次数据元素的比较次数均为1,数据元素的赋值语句执行次数均为2。因此整个排序过程中的比较次数为n-1,赋值语句执行次数为2(n-1).所以直接插入排序算法最好情况下的时间复杂度为O(n)

最坏的情况:原始数据反序排列。while内层每次均为i。外层for的:

    比较次数:(n-1)(n+2)/2

    移动次数:(n-1)(n+4)/2

    因此此时的时间复杂度为:O(n2) n平方


随机的情况:那么数据元素的期望比较次数和期望移动次数为n2/4,所以此时期望时间复杂度为:O(n2)


即,序列初始越有序,则直接插入排序算法的时间效率越高。

空间复杂度

O(1)

稳定性

由它的执行过程可知,直接插入排序是稳定的排序算法