插入排序

113 阅读2分钟

总结

  • 插入排序的基本思想就是不断扩展有序序列的长度

    具体方式是对于一个有序序列,如果想在其中新加入一个元素,就应通过插入操作找出正确的插入位置,并且将插入位置空出来,然后插入新元素。

  • 插入操作的基本思想就是从后向前不断“试探”分界线的位置

    一个合法的分界线,分界线前的元素需满足小于等于新元素大小,分界线后元素需满足大于新元素大小。所以寻找分界线的过程,就是不断把当前在分界线前,但本应该在分界线后的元素向后移动。

  • 插入操作的算法描述:

    1. 假设序列1~(i-1)已经有序, 从i1枚举分界线的下标j;
    2. 如果分界线前面的元素a[j-1]大于x,说明a[j-1]应该在分界线后面。所以将a[j-1]移动到a[j],分界线前移变成j-1
    3. 如果分界线前面没有元素(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)O(n2)。