排序算法01-插入排序

1. 基本思想   

    插入排序是对少量元素进行排序的有效算法。插入排序的过程很简单,将待排序的表List分成已排序和未排序的两个部分(如图1所示),将未排序中的元素依次插入已排序的表中。具体做法是取出未排序表中的一个元素,将之与已排序的表中元素依次进行比较,直至找到正确位置。则将该元素插入到该位置,重复这个步骤,直至未排序中元素全部插入已排序的表中。

                                                                                             (图1)

2. 算法实现

      这里使用模板来实现,以增强代码的实用性。

 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,开始下一次的插入。

 终止:在内层循环中,当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  利用概率论知识分析插入排序算法

        待续。。。

 

 

posted @ 2013-10-14 23:24  DreamTop  阅读(228)  评论(0编辑  收藏  举报