折半插入排序——考研算法

一.基本原理

1.核心思想: 折半插入排序在寻找插入位置时,不是逐个比较而是利用折半查找的原理寻找插入位置 。待排序元素越多,改进效果越明显。
2.算法分析:

设数组为a[0…n]。

  1. 将原序列分成有序区和无序区。a[0…i-1]为有序区,a[i…n] 为无序区。(i从1开始)
  2. 从无序区中取出第一个元素,即a[i],使用二分查找算法在有序区中查找要插入的位置索引j。
  3. 将a[j]到a[i-1]的元素后移,并将a[i]赋值给a[j]。
  4. 重复步骤2~3,直到无序区元素为0。

二.图例演示:

如上图所示,以一组数据{15,27,36,53,69} 和42为例,进行折半插入排序的算法演示:

 1. 初始化:默认low下标为0,high下标为4,mid=(low+high)/2;
 2. 第一次对比:a[mid]=36<42,则low=mid+1;
 3. 第二次对比:mid=(3+4)/2=3,a[mid]=53>42;则high=mid-1;
 4. 查找结束:此时high<low,跳出循环,原a[mid]后的数后移;
 5. 插入:a[mid]=42;

三.代码实现

void BinsertSort(RedType L, int n)
{  int i,low,high,mid;
  for(i=2; i<=n; ++i){
      L[0]=L[i];    /* r[0]作为监视哨*/
      low=1; high=i-1;
      While(low<=high)
      {mid=(low+high)/2;
       if (L[0].key<L[mid].key) high=mid-1;       //插入点在低半区
       else low=mid+1;   }  
      for( j=i-1; j>=high+1;  j )
     L[j+1]=L[j];                                             /*  记录后移*/
     L[high+1]=L[0];                                     /*  插入*/
     } /* for*/
 }/*折半插入排序*/


四.性能分析

0、
1 时间复杂度:

(1)顺序排列时,只需比较(n-1)次,插入排序时间复杂度为O(n); 
(2)逆序排序时,需比较n(n-1)/2次,插入排序时间复杂度为O(n^2); 
(3)当原始序列杂乱无序时,平均时间复杂度为O(n^2)。

2 空间复杂度:

插入排序过程中,需要一个临时变量temp存储待排序元素,因此空间复杂度为O(1)。

3 算法稳定性:

折半插入排序也是一种稳定的排序算法,。

下一节预告

下一节将讲解插入排序中的希尔排序算法

猜你喜欢

转载自blog.csdn.net/Gnewocean/article/details/84887251