一、算法基本思想
借助折半查找的思想,折半插入排序的基本思想是先利用折半查找找到相应插入的位置,再对元素进行移动。
例如:
10 | 5 | 25 | 16 | 23 |
第一轮:从第二个元素开始折半插入;此时low和high同指向元素10,满足low<=high,且5<10;则元素5应该插入在元素10之前,同时元素10后移一位,移动后结果为:
5 | 10 | 25 | 16 | 23 |
第二轮:low指向元素5,high指向元素10,满足low<=high,所以mid指向5,而元素25>5,所以low=mid+1,即low指向元素10;也满足low<=high,再次折半查找,结果是无需移动元素25.
第三轮:low指向元素5,high指向元素25,满足low<=high,所以mid指向10,而元素16>10,所以low=mid+1,即low指向元素25;也满足low<=high,再次折半查找,元素16<25,所以将元素16插入25之前,同时元素25后移一位,移动后结果为:
5 | 10 | 16 | 25 | 23 |
第四轮:low指向元素5,high指向元素25(即顺序表中第四个元素),满足low<=high,所以mid指向10,而元素23>10,所以low=mid+1,即low指向元素16;也满足low<=high,再次折半查找,元素16<23,所以low=mid+1,即low指向元素25;也满足low<=high,再次折半查找,所以将元素23插入25之前,同时元素25后移一位,移动后结果为:
5 | 10 | 16 | 23 | 25 |
二、代码实现
1、算法代码
void Half_InsertSort(int A[],int n){
int i,j,low,high,mid,temp;
for(i=1;i<n;i++){
temp=A[i];
low=0;
high=i-1;
while(low<=high){
mid=(low+high)/2;
if(temp<A[mid])
high=mid-1;
else
low=mid+1;
}
for(j=i-1;j>=high+1;--j)
A[j+1]=A[j];
A[high+1]=temp;
}
}
2、测试结果
三、算法分析
1、性能分析
空间效率:仅使用了常数个辅助单元,所以其空间复杂度为O(1)。
时间效率:折半插入排序仅减少了元素的比较次数,而元素的移动次数并未改变,它依赖于待排序表的初始状态。因此,折半插入排序的时间复杂度为O(n²)。
2、稳定性
不会出现相同元素的相对位置发生变化,即折半插入排序算法是一个稳定的排序算法。
3、适用性
仅适用于顺序存储的线性表