插入排序

一. 直接插入排序(稳定)

算法原理

将一个记录插入到已经排好序的有序表中,从而得到一个新的,长度增加1的有序表。
【每遍操作】
现将元素复制到0号位置(哨兵),再将本元素同已排序的序列,从尾开始比较。在已排序的序列中寻找自己的位置,进行插入;或者寻找不到,则一直进行到哨兵为止,即本元素最小,应放置在1号位置。

算法代码

   template <typename Comparable>
   void insertSort( vector<Comparable>& a )
   {
       for ( int i = 1; i < a.size(); ++i )
       {
             Comparable temp = a[i];
          int j = i - 1;
            for ( ; j >= 0 &&a[j] > temp ; --j)
                        a[j+1] = a[j];
           a[j+1] = temp;
      } 
  }

 python版本

def insertSort(data):
    """直接插入排序(有小到大)"""
    n = len(data)
    for i in range(1, n):
        temp = data[i]
        j = i - 1
        while j >= 0 and data[j] > temp:
            data[j+1] = data[j]
            j -= 1

        data[j+1] = temp

    return data

 

 

 性能分析:

空间复杂度O(1)

时间复杂度:O(N2)

  • 正序时:比较次数n-1次,移动次数0次
  • 逆序时:比较次数和移动次数都是O(N2)

 二. 折半插入排序(稳定)

算法原理

 在插入排序基础上进行改进。每次在有序表中查找插入位置时,不按照顺序挨个查找,而是先与有序表中中间的元素进行比较,这样可以查找范围缩至原来的一半。

需要注意的问题

 【具体操作】
        在将一个新元素插入有序表中时,将首元素设为a[low],末元素设为a[high],将待插入元素a[i]
与中间元素m=(low+high)/2相比较,如果比它大,则更新low = m+1,否则 high = m-1,直到low<=high不成立,即将此位置之后所有元素后移一位,并将新元素插入到a[high+1].
需要注意的问题
1.必须采用顺序存储方式
2.折半插入排序的比较次数与记录移动次数与初始状态无关,仅依赖于记录的个数。
 

算法代码

 1 void halfInsertSort ( vector<Comparable>& a )
 2 {
 3     for (int i = 1; i < a.size(); ++i)
 4    {
 5          Comparable temp = a[i];
 6          int low = 0, high = i-1;
 7          while ( low <= high )
 8          {
 9              int mid = ( low + high ) / 2;
10              if ( a[mid] <= temp )
11                     low = mid + 1;
12              else
13                     high = mid - 1;
14          }//插入位置为low,low到i-1的元素后移
15        for ( int j = i - 1; j >= low; --j )
16            a[j+1] = a[j];
17        a[low] = temp;  
18     }  
19 }

 python版本

def halfInsertSort(data):
    """折半插入"""
    for i in range(1, len(data)):
        temp = data[i]
        low, high = 0, i-1
        while low <= high:
            mid = (low + high) // 2
            if data[mid] <= temp:
                low = mid + 1
            else:
                high = mid - 1
        # 插入位置为low, low~i-1后的元素后移
        for j in range(i-1, low-1, -1):
            data[j+1] = data[j]

        data[low] = temp

    return data

算法性能

  • 时间复杂度:O(N2)
  • 空间复杂度:O(1)
  • 优势:减少比较次数,移动次数不变

三.希尔排序

template< typename Comparable >
void shellSort (vector<Comparable>&a)
{//使用希尔增量,a.size()/2, a.size()/4,...1
   for (int gap = a.size()/2; gap > 0; gap /= 2)
      for (int i = gap; i < a.size(); ++i)
      {
          Comparable temp = a[i]; 
    int j = i-gap;   
          for (; j >= 0 && a[j] > temp; j-=gap)//直接插入法
                a[j+gap] = a[j];//边查找边后移
          a[j+gap] = temp;
       } 
}

 

posted @ 2015-07-13 15:01  Rosanne  阅读(251)  评论(0编辑  收藏  举报