直接插入排序是在有序序列中从后往前一个一个比较来寻找插入位置J的,这样比较次数相对比较繁琐,也可以通过二分法来寻找插入位置J,具体思路如下:
- 寻找插入位置J
开始将前面有序序列第一个元素的位置(0)标记为low,最后一个元素的位置(i-1)标记为high,mid=(high+low)/2;通过不断使a[mid]与取得数a[i]进行比较,由于前面的序列是有序的,所以,如果tmp比a[mid]大,则说明是需要在mid 后半段进行寻找位置J,(low=mid+1); 如果tmp比a[mid]小,则说明需要在前半段寻找位置J,(high=mid-1).直到low==high,这个时候 low/high就是需要差入的位置了.
- 不断后移动插入取数a[i]
将i-1到high/low位置的元素不断后移一位
相较于直接插入排序减少了比较次数,但是没有减少移动次数,平均性能优于直接插入排序
时间复杂度为O(n^2) 空间复杂度为O(1) ,是一种稳定的排序方法。
程序如下:
//二分法插入排序
void insertBinary(int a[], int n){
int i, j, tmp;
int low, mid, high;
for(i=1; i<n; i++){
tmp = a[i];
low=0; high = i-1;
/* 1.寻找插入位置J */
while(low<=high){
mid = (low+high)/2;
if(tmp>a[mid]) low = mid + 1; //如果取的数据比中间的大,则说明需要在mid右边寻找位置J
else high = mid - 1;
}
/* 2.后移插入位置 */
//从位置i到位置J(low/high)依次后移动一位
for(j=i; j>low; j--){
a[j]=a[j-1];
}
a[low]=tmp;
}
}