经典排序算法——插入排序

插入排序原理

插入的排序的原理是每趟将一个数按照大小插入到它前面已经排好序的子序列中。依次重复,直到插入所有数字。算法

图解插入排序原理(升序为例)

以数组[3,4,1,2]为例,升序排列数组。数组

第一趟从第2个数据开始(第1个数字本身已经有序),跟前面一个数字比较,若是小于前面数字就将前面数字后移,并继续向前比较,直到下标小于0为止。以下图所示dom

 

第二个数字4,插入到它前面的有序子序列(3)中,因为4>3因此直接插在3后面即无需移动。第一趟结束。指针i向后移,以下图所示测试

 

第三个数字1,插入到它前面的有序子序列(3,4)中,因为1<4因此将4后移一位(数字1会先保存起来,没必要担忧被覆盖),而后再让1与3比较,1<3,因此3后移一位。子序列遍历完后,将数字1放入插入位置。接着i指针后移,以下图所示优化

 

通过3趟比较后,数组中的数字已经排好顺序。下面看下具体代码spa

 1 public static void sort(int[] array){
 2         for (int i = 1; i <array.length ; i++) {
 3             int insertValue = array[i];
 4             int insertIndex = i -1 ;
 5             while (insertIndex >= 0 && insertValue < array[insertIndex]){
 6                 //待插入数字小于前面下标对应的数
 7                 array[insertIndex+1] = array[insertIndex];
 8                 insertIndex --;
 9             }
10             //位置找到 为insertIndex + 1
11             array[insertIndex + 1] = insertValue;
12         }
13     }

代码分析

1)第一个for循环用于肯定比较趟数,i从1开始(前面有1个数,1个数的子序列确定有序)到数组最后一个数字3d

2)记录当前要插入到前面子序列的值(防止子序列数字后移覆盖)指针

3)while依次序循环子序列,当子序列中数字大于要插入的数字时继续向前遍历,直到找到比当前数字更小或子序列遍历完,插入对应位置code

时间复杂度

从代码可知,插入排序有两层循环,因此其时间复杂度为T(n)=O(n^2)blog

测试算法执行效率

与前面的排序算法相同,咱们依然生成10万个随机数的数组,使用插入排序方法进行排序,看其执行时间。测试代码以下

1 public static void main(String []args){
2         int[] array = new int[100000];
3         for (int i=0; i<100000; i++){
4             array[i] = (int)(Math.random()*800000);
5         }
6         long begin = System.currentTimeMillis();
7         sort(array);
8         System.out.println("总耗时="+(System.currentTimeMillis() - begin));
9     }

测试结果

 

能够看到插入排序算法比选择排序更快,10万个数据的数组排序大概须要1秒多时间。下篇咱们将介绍基于插入算法的优化算法 --希尔排序算法,排序效率是否会更高呢?一块儿期待!

总结

插入排序算法的思路是从数组的第二个数开始,插入到它前面的有序子序列。依次遍历数组,直到遍历完全部数据后,数组即变为有序。

相关文章
相关标签/搜索