算法_插入排序之折半插入排序

基本思想

考虑到直接插入排序的基本思想就是每次将无序区里的元素插入到有序区,那么可以利用表的有序性在有序区中使用折半查找查找插入位置。

对于递增有序表,我们查找插入位置就是第一个关键字大于插入元素关键字的元素位置,因此折半插入就需要查找有序区中第一个关键字大于要插入元素关键字的元素位置。

综合以上分析 ,可以采用与直接插入排序相同的方法,扫描无序曲,依次比较元素,然后元素插入的位置使用折半查找,然后移动插入位置后的有序区元素,最后进行元素插入。

实现

void bin_sort(RecType R[], int n)
{
    int i, j, low, mid, high;
    RecType tmp;
    for (i=1; i<n; i++)
        if (R[i].key < R[i-1].key)
        {
            tmp = R[i];
            low = 0;
            high = i-1;
            while (low <= high)
            {
                mid = (low + high) / 2;
                if (tmp.key < R[mid].key)
                    high = mid - 1;
                else
                    low = mid + 1;
            }
            for (j=i-1; j>=high+1; j--)
                R[j+1] = R[j];
            R[high+1] = tmp;
        }
}

算法分析

时间复杂度

平均比较次数与折半查找的判定树有关,因此R[i]插入到有序区的平均比较次数为
l o g 2 ( i + 1 ) − 1 log_2{(i+1)-1} log2(i+1)1
平均移动次数与直接插入排序一样,都为
i 2 + 2 \frac i2 + 2 2i+2
综上,平均时间复杂度为
∑ 1 n − 1 ( l o g 2 ( i + 1 ) − 1 + i 2 + 2 ) = O ( n 2 ) \sum_1^{n-1}(log_2(i+1)-1 + \frac i2 + 2) = O(n^2) 1n1(log2(i+1)1+2i+2)=O(n2)

空间复杂度

很显然,折半插入排序是一个原地工作算法,其所需临时空间相对于问题规模来说是常数,所以空间复杂度为
O ( 1 ) O(1) O(1)

稳定性

折半插入排序将元素插入到有序区中第一个关键字大于它的元素的位置,与相同关键字元素的相对位置不改变,所以是稳定的排序算法

适用情况

相对于直接插入排序,平均时间复杂度没有改善,而在查找插入位置的比较次数方面的效率得到了提高。折半插入排序适用于

数据量较小,且基本有序的情况

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值