算法熟记-排序系列-插入排序

1. 简述

    假设待排序数组为 int array[], 数组长度为n。

    第1趟,认为array[0]-array[0]已经排序,把array[1]插入到合适的位置。
    第2趟,认为array[0]-array[1]已经排序,把array[2]插入到合适的位置。
    ···
    第n-1趟,认为array[0]-array[n-2]已经排序,把array[n-1]插入到合适的位置。

2. 复杂度

    最好的时间复杂度是O(n),对已经排序好的数组,只需要n-1次比较就可以了。平均时间复杂度和最坏时间复杂度都是O(n^2)。
    在每次趟中,寻找合适位置时,可以使用二分查找的方法,来减少比较次数。
    稳定性上,如果不使用二分查找,那么是稳定的排序,否则是不稳定的排序。

3. 代码

void  insertion_sort( int  array[],  int  n) {
  
int  pos, left, right, mid, tmp;
  
for ( int  i = 1 ; i < n; i ++ ) {
    
if (array[i]  >=  array[i - 1 ]) {  //  不需要插入
       continue ;
    }
    
else   if (array[i]  <  array[ 0 ]) {  //  插入到最前面
      pos  =   0 ;
    }
    
else  {  //  使用二分查找,来确定插入位置
      left  =   0 ; right  =  i - 1 ;
      
while (right  -  left  >   1 ) {
        mid 
=  (left + right) / 2 ;
        
if (array[i]  <  mid) right  =  mid;
        
else  left  =  mid;
      }
      pos 
=  right; 
    }
    
//  插入过程
    tmp  =  array[i];
    
for ( int  j = i; j > pos; j -- )
      array[i] 
=  array[i - 1 ];
    array[pos] 
=  tmp;
  }
}

    实际上,插入排序的元素赋值操作往往是比较耗时的,二分的方法只能减少一些比较的次数,并不能减少元素移动的次数,因此对于性能提升不是很多。下面给出一个比较“简化”的插入排序代码:    

void  insertion_sort( int  array[],  int  n) {
  
int  temp,i,j;
  
for (i = 1 ; i < n; i ++ ) {
    temp 
=  array[i];
    
for (j = i; j > 0   &&  temp < array[j - 1 ]; j -- ) {  //  此时array[j]==temp
      array[j]  =  array[j - 1 ];
    }   
    array[j] 
=  temp; 
  }
}

上面代码举个例子来说明一下,比如对1 3 4 5 6 7 2,现在要把最后的2插入到前面有序的数组中了,首先,temp=2,然后就用temp与前面的这些数字逐个比较,如果temp更小,那么就把前面的数字后移一位,直到结束,在把temp放到空出的位置。对于例子就是在循环结束时,1 3 3 4 5 6 7 ,temp=2, j=1,然后array[1]=2,得到1 2 3 4 5 6 7

4. 参考资料

   维基百科-插入排序   http://en.wikipedia.org/wiki/Insertion_sort

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值