重学算法之插入排序
算法介绍
1.把所有的元素分为两组,已经排序的和未排序的;
2.找到未排序的组中的第一个元素,向已经排序的组中进行插入;
3.倒叙遍历已经排序的元素,依次和待插入的元素进行比较,直到找到一个元素小于等于待插入元素,那么就把待 插入元素放到这个位置,其他的元素向后移动一位;
及时交换,代码实现
package com.hy.sort.insertsort; import java.util.Arrays; /** * @author hanyong * @date 2020/11/28 10:02 */ public class InsertSort { /** * 大于0说明c1大与c2 * * @param c1 * @param c2 * @return */ private boolean isBigger(Comparable c1, Comparable c2) { return c1.compareTo(c2) > 0; } /** * 交换数组对应索引的值 * * @param comparables * @param i * @param j */ private void exchange(Comparable[] comparables, int i, int j) { Comparable temp = comparables[i]; comparables[i] = comparables[j]; comparables[j] = temp; } private void insertSort(Comparable[] comparables) { for (int i = 1; i < comparables.length; i++) { for (int j = i; j > 0; j--) { if (isBigger(comparables[j - 1], comparables[j])) { exchange(comparables, j, j-1 ); } else { break; } } } } public static void main(String[] args) { Integer[] nums={17,5,1,6,9,3}; InsertSort insertSort=new InsertSort(); insertSort.insertSort(nums); System.out.println(Arrays.toString(nums)); } }
韩顺平版算法思想:
把n个待排序的元素看成一个有序表和一个无序表,开始时有序表只含一个元素,无需表中含有n-1个,排序过程中每次从无序表中取一个元素,把它的排序码依次与有序表的排序码也就是数值进行比较,将它插入到有序表适当位置,使之成为有序表。
动图演示原理:
代码演示:
package com.hy.sort.insertsort; import java.util.Arrays; /** * @author hanyong * @date 2020/11/28 10:33 */ public class TraditionInsortSort { public void insort(int[] nums) { for (int i = 1; i < nums.length; i++) { int temp = nums[i]; int j = i; while (j > 0 && nums[j - 1] > temp) { nums[j] = nums[j - 1]; j--; } nums[j]=temp; } } public static void main(String[] args) { int[] nums={17,5,1,6,9,3}; TraditionInsortSort traditionInsortSort=new TraditionInsortSort(); traditionInsortSort.insort(nums); System.out.println(Arrays.toString(nums)); } }
插入排序的时间复杂度分析 插入排序使用了双层for循环,其中内层循环的循环体是真正完成排序的代码,所以,我们分析插入排序的时间复 杂度,主要分析一下内层循环体的执行次数即可。 最坏情况,也就是待排序的数组元素为{12,10,6,5,4,3,2,1},那么: 比较的次数为: (N-1)+(N-2)+(N-3)+...+2+1=((N-1)+1)*(N-1)/2=N^2/2-N/2; 交换的次数为: (N-1)+(N-2)+(N-3)+...+2+1=((N-1)+1)*(N-1)/2=N^2/2-N/2; 总执行次数为: (N^2/2-N/2)+(N^2/2-N/2)=N^2-N; 按照大O推导法则,保留函数中的最高阶项那么最终插入排序的时间复杂度为O(N^2)