算法描述
1,从第一个元素开始,该元素默认被排序;
2,取出下一个元素(新元素key),然后在已经排序的元素序列中从后向前扫描;
3,如果已排序的序列中的元素大于新元素,将该元素移向下一位置;
4,重复步骤3,直到找到小于新元素的该元素(data[position-1]);
5,将新元素插入到该元素后面
6,重复2~5。
Java代码实现
1 /** 2 * 插入排序的算法思想: 假设第一个元素为已排序数列,遍历剩余的未排序数列 如果已排序数列中的元素<=该元素(key),则将该元素(key)放在其后面一位。继续遍历未排序数列。 3 * 如果已排序数列中的元素>该元素(key),则将已排序数列中的该元素后移一位,继续寻找。 4 */ 5 public class Insertion 6 { 7 public static <T extends Comparable<? super T>>void insertionSort(T data[]) 8 { 9 for(int index = 1; index < data.length; index++) 10 { 11 // 从未排序数列中挑出要被插入到已排序数列中的元素key。 12 T key = data[index]; 13 // key在已排序数列中的最终位置设为position 14 int position = index; 15 //比较次数:(n-1)~n(n-1)/2 16 while(position > 0 && data[position - 1].compareTo(key) > 0) 17 { 18 // 如果已排序数列中的元素值大于要被插入的新元素key,则将已排序数列中的该元素后移一位 19 data[position] = data[position - 1]; 20 // 继续往前寻找符合条件(小于新元素key)的旧元素,直到序列的起点0 21 position--; 22 } 23 // 将要被插入的新元素key放在符合条件的元素的后面,即position处。 24 data[position] = key; 26 } 27 } 28 29 public static void main(String[] args) 30 { 31 Integer[] c = {12, 33, 2, 55, 34, 877, 6, 77, 33, 12, 4, 6, 32, 7, 5, 5, 56, 4, 3, 6, 4, 34, 44555}; 32 insertionSort(c); 33 for(Integer i: c) 34 { 35 System.out.print(i+" "); 36 } 37 } 38 }
时间复杂度:
如果目标是要把n个元素的序列升序排列,那么采用插入排序存在最好情况和最坏情况。最好情况就是,序列已经是升序排列了,在这种情况下,需要进行的比较操作需(n-1)次即可。最坏情况就是,序列是降序排列,那么此时需要进行的比较共有n(n-1)/2次。平均来说插入排序算法复杂度为O(n2)。因而,插入排序不适合对于数据量比较大的排序应用。但是,如果需要排序的数据量很小,例如,量级小于千,那么插入排序还是一个不错的选择。 插入排序在工业级库中也有着广泛的应用,在STL的sort算法和stdlib的qsort算法中,都将插入排序作为快速排序的补充,用于少量元素的排序(通常为10个或以下)。