1. 基本思想 算法
插入排序是对少许元素进行排序的有效算法。插入排序的过程很简单,将待排序的表List分红已排序和未排序的两个部分(如图1所示),将未排序中的元素依次插入已排序的表中。具体作法是取出未排序表中的一个元素,将之与已排序的表中元素依次进行比较,直至找到正确位置。则将该元素插入到该位置,重复这个步骤,直至未排序中元素所有插入已排序的表中。数组
(图1)spa
2. 算法实现code
这里使用模板来实现,以加强代码的实用性。blog
1 template<class T> 2 void insert_sort(T* a,int n) 3 { 4 for(int i=1;i<n;i++) 5 { 6 T key=a[i]; 7 // insert key(namely a[i]) into the sorted sequence a[0..i-1] 8 int j=i-1; 9 while(key<a[j] && j>=0) 10 { 11 a[j+1]=a[j]; 12 j--; 13 } 14 a[j+1]=key; 15 } 16 }
3. 算法分析排序
3.1 算法可行性(循环不变式):内存
初始条件:在算法开始时,将要排序的表分割成A[0]和A[1..n-1].而左边的表A[0]为已排序的表,A[0]中只包含一个元素,显然成立,右边A[1..n-1] 为未排序的表。模板
保持:在两层循环中,目的是将元素A[i]插入到A[0..i-1]的正确位置中。它将从A[j-1]开始依次与已排序中的元素进行比较,直至找到一个位置k使得A[j-1]>=A[k]或者已经找到已排序的表头为止。而后将该元素插入到该位置。而后将i+1,开始下一次的插入。class
终止:在内层循环中,当A[i]插入到已排序的表中终止内层循环。在外层循环中,当因此未排序的表的元素都插入到已排序的表中,即i=n时,算法终止。终止时,已排序的表长为n,未排序的表长为0,代表已将A[0..n-1]排完序。基础
3.2 时间复杂度
最坏状况:O(n^2);
最好状况:O(n)。
当输入的待排序的序列已经排好序,则只须要进行n-1比较就能够完成排序。故最好的状况下,算法的复杂度为O(n)。当输入的待排序的序列为彻底逆序,即由大到小排列时,须要进行1+2+3+...+n-1=0.5n(n-1)次比较才能够完成排序。故最坏状况下,算法复杂度为O(n^2)。其余状况介于这两种状况之间。
3.3 空间复杂度
插入排序是在原数组的基础上进行的排序,咱们称之为原地排序(即只有常数个元素被存放到数组之外的空间中去)。可见插入排序对内存的使用率仍是很高的,不会白白浪费内存空间。因此它的空间复杂度为O(n).
3.4 利用几率论知识分析插入排序算法
待续。。。