插入排序算法

文章详细介绍了插入排序的工作原理,包括其原地排序特性,平均和最坏时间复杂度为O(N^2),以及稳定的排序性质。此外,还提供了插入排序的代码实现。接着,讨论了在插入排序中采用二分查找来优化插入位置,从而提高效率,二分插入排序的时间复杂度降低到O(NlogN)。最后,给出了二分插入排序的代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

插入排序(Insertion-Sort)的算法

插入排序的工作原理是通过将数据分为已经排序的有序数据和未排序数据,通过逐步将未排序数据添加到有序数据中,在已排序序列中从后向前扫描,找到相应位置并插入。插入排序在实现上,通常采用原地排序(in-place:即只需用到O(1)的额外空间的排序),因而在从后向前扫描已排序数据的时候,需要反复把已排序元素逐步向后挪位,为最新元素提供插入空间

算法实现

① 从第一个元素开始,该元素可以认为已经被排序

② 取出下一个元素,在已经排序的元素序列中从后向前扫描

③如果该元素(已排序)大于新元素,将该元素移到下一位置

④ 重复步骤③,直到找到已排序的元素小于或者等于新元素的位置

⑤将新元素插入到该位置后

⑥ 重复步骤②~⑤

代码实现:

void InsertSort(int arr[], int len){
    // 输入检查
    if(arr == NULL || len <= 0){
        return;
    }
    for(int i = 1; i < len; i++){
        int tmp = arr[i];
        int j;
        for(j = i-1; j >= 0; j--){
            //如果比需要插入的数据大,把值往后移动一位
            if(arr[j] > tmp){
               arr[j+1] = arr[j];
            }
            else{
               break;
            }
        }
        //将需要插入的数据放到合适的位置
        arr[j+1] = tmp;
    }
}

性能分析

平均时间复杂度:O(N^2)

最差时间复杂度:O(N^2)

空间复杂度:O(1)

排序方式:In-place

稳定性:稳定

如果插入排序的目标是把n个元素的序列升序排列,那么采用插入排序存在最好情况和最坏情况:

(1) 最好情况:序列已经是升序排列,在这种情况下,需要进行的比较操作需(n-1)次即可。

(2) 最坏情况:序列是降序排列,那么此时需要进行的比较共有n(n-1)/2次。

算法优化改进

直接插入排序每次往前插入时,是按顺序依次往前查找,数据量较大时,必然比较耗时,效率低。在往前找合适的插入位置时采用二分查找的方式,即折半插入

二分插入排序相对直接插入排序而言:平均性能更快,时间复杂度降至O(NlogN),排序是稳定的,但排序的比较次数与初始序列无关,相比直接插入排序,在速度上有一定提升。逻辑步骤:

① 从第一个元素开始,该元素可以认为已经被排序

② 取出下一个元素,在已经排序的元素序列中二分查找到第一个比它大的数的位置

③将新元素插入到该位置后

④ 重复上述两步

代码实现:

void BinaryInsertSort(int arr[], int len)   
{   
    int key, left, right, middle;   
    for (int i=1; i<len; i++)   
    {   
        key = a[i];   
        left = 0;   
        right = i-1;   
        while (left<=right)   
        {   
            middle = (left+right)/2;   
            if (a[middle]>key)   
                right = middle-1;   
            else   
                left = middle+1;   
        }   

        for(int j=i-1; j>=left; j--)   
        {   
            a[j+1] = a[j];   
        }   

        a[left] = key;          
    }   
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值