C++算法之插入排序

C++算法之插入排序



一、算法描述

整理插入排序算法描述如下:

  • 枚举序列中第2~n个元素。
  • 当枚举元素i时,前i-1个元素已经有序。将第i个元素插入到前i-1个元素的有序序列中,形成长度为i的有序序列。
  • 枚举过程结束后,整个序列有序。

在上述算法描述中,我们有个关键的步骤——插入操作:将第i个元素插入到前i-1个元素的有序序列中,形成长度为i的有序序列。

怎样实现这个过程呢?

一种实现思路和前面介绍的“火车站插队”过程十分类似。比如对于如下序列:
在这里插入图片描述
这个序列的前4个元素已经有序,现在我们要把2插入到前4个元素中去。

1、首先让2出队。
在这里插入图片描述
2、然后将其与6比较,发现2<6,说明2应该在6前面。所以我们将6向后移动。

3、再将其与5比较,发现2<5,说明2应该排在5前面。所以我们将5向后移动。
在这里插入图片描述
在这里插入图片描述
4、经过同样的分析,4也应该向后移。
在这里插入图片描述
5、最后我们将21比较,发现1<2,说明2应该放在1的后面。正好经过前面的移动,1后面有一个空位,所以我们把2插入在这个空位中。
在这里插入图片描述
以上就是我们将一个新的元素2插入前面有序序列a的过程。

因为前面的序列有序,所以在整个序列中一定有一条分界线j,使得分界线前面的元素(i<j),都满足a[i]<=2;

对于分界线及分界线以后的元素(i>=j),都满足a[i]>2;

所以,上面的移动一定可以将分界线及以后的元素向后移动一位,空出分界线的位置j,然后将2插入到j号元素中。

所以,我们总结一下插入操作的算法描述:

  • 假设序列1~(i-1)已经有序, 从i1枚举分界线的下标j;

  • 如果分界线前面的元素a[j-1]大于x,说明a[j-1]应该在分界线后面。所以将a[j-1]移动到a[j],分界线前移变成j-1

  • 如果分界线前面没有元素(j=1),就将x放在数组第1位。否则如果碰到一个j-1号元素小于等于x,说明分界线位置正确,就将x插到j位。


二、代码实现

代码如下(示例):

#include <bits/stdc++.h>
#define N 1550
using namespace std;
int a[N], n;

int main() {
    // 输入
    cin >> n; 
    for (int i = 1; i <= n; ++i) cin >> a[i];
	
    // 插入排序
    for (int i = 2; i <= n; ++i) {    // 按照第2个到第n个的顺序依次插入
        int j, x = a[i];    // 先将i号元素用临时变量保存防止被修改。

        // 插入过程,目的是空出分界线位置j,使得所有<j的部分<=x,所有>j的部分>x。
        // 循环维持条件,j>1,并且j前面的元素>x。
        for (j = i; j > 1 && a[j - 1] > x; --j) {   
            // 满足循环条件,相当于分界线应向前移,
            // 分界线向前移,就等于将分界线前面>x的元素向后移
            a[j] = a[j - 1];              
                                                    
        }
        // 找到分界线位置,插入待插入元素x
        a[j] = x;                         
    }
	
    // 输出
    for (int i = 1; i <= n; ++i) cout << a[i] << ' ';
    cout << endl;
    return 0;
}

三、复杂度分析

插入排序的总时间复杂度是O(n^2)

  • 16
    点赞
  • 65
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值