CSP-J/S冲奖第21天:插入排序

boyanx2个月前技术教程11

一、插入排序概念

1.1 生活中的类比

o 扑克牌排序:就像整理手中的扑克牌,每次将一张牌插入到已排好序的牌中合适位置
o 动态演示
初始序列:[5, 2, 4, 6, 1, 3]
排序过程:
→ [2, 5, 4, 6, 1, 3]
→ [2, 4, 5, 6, 1, 3]
→ ... → [1, 2, 3, 4, 5, 6]

1.2 算法特点

特性说明
时间复杂度平均 O(n^2),最好 O(n),最坏 O(n^2)
空间复杂度O(1)(原地排序)
稳定性稳定排序算法
适用场景小规模数据/部分有序数据

二、算法实现步骤

2.1 核心思想

  1. 将数组分为已排序区间未排序区间
  2. 初始时已排序区间只包含第一个元素
  3. 每次从未排序区间取一个元素,在已排序区间找到合适位置插入
  4. 重复直到所有元素有序

2.2 详细步骤

对于 i 从 1 到 n-1:
   1. 将 arr[i] 存入临时变量 temp
   2. 从 i-1 开始向前遍历,将比 temp 大的元素后移
   3. 找到合适位置后插入 temp

三、C++代码实现

3.1 基础版本

#include <iostream>
using namespace std;

void insertionSort(int arr[], int n) {
    for (int i = 1; i < n; i++) {
        int temp = arr[i];
        int j = i - 1;
        // 将比temp大的元素后移
        while (j >= 0 && arr[j] > temp) {
            arr[j+1] = arr[j];
            j--;
        }
        arr[j+1] = temp; // 插入正确位置
    }
}

int main() {
    int arr[] = {524613};
    int n = sizeof(arr)/sizeof(arr[0]);
    
    insertionSort(arr, n);
    
    cout << "排序结果:";
    for (int i = 0; i < n; i++) {
        cout << arr[i] << " ";
    }
    return 0;
}

3.2 运行结果

排序结果:1 2 3 4 5 6 

四、算法解析

4.1 关键代码分析

while (j >= 0 && arr[j] > temp) {
    arr[j+1] = arr[j];
    j--;
}
  • 边界条件j >= 0 防止数组越界
  • 移动操作:比当前元素大的值逐个后移
  • 插入位置:循环结束后 j+1 即为正确位置

4.2 性能优化

o 提前终止:当元素已在正确位置时,可提前结束内层循环
o 二分查找优化:使用二分查找确定插入位置(减少比较次数,移动次数不变)


五、常见错误与调试

5.1 典型错误

错误类型示例代码解决方案
数组越界int j = i(初始值错误)确保 j 初始值为 i-1
丢失元素忘记赋值 arr[j+1] = temp保证最后执行插入操作
无限循环while (j > 0) 缺少终止条件添加 j >= 0 边界判断

5.2 调试技巧

  1. 打印中间过程
cout << "第" << i << "轮排序:";
for (int k=0; k<n; k++) cout << arr[k] << " ";
cout << endl;
  1. 单元测试
// 测试完全逆序数组
int test1[] = {5,4,3,2,1};
// 测试已有序数组
int test2[] = {1,2,3,4,5};

六、实战练习

6.1 基础题

题目:实现降序排列的插入排序
参考代码

void insertionSortDesc(int arr[], int n) {
    for (int i = 1; i < n; i++) {
        int temp = arr[i];
        int j = i - 1;
        while (j >= 0 && arr[j] < temp) { // 修改比较方向
            arr[j+1] = arr[j];
            j--;
        }
        arr[j+1] = temp;
    }
}

6.2 进阶题

题目:统计插入排序过程中元素移动的总次数
实现思路

int insertionSortCount(int arr[], int n) {
    int count = 0;
    for (int i = 1; i < n; i++) {
        int temp = arr[i];
        int j = i - 1;
        while (j >= 0 && arr[j] > temp) {
            arr[j+1] = arr[j];
            j--;
            count++; // 每次移动计数
        }
        arr[j+1] = temp;
    }
    return count;
}

七、复杂度分析

情况时间复杂度说明
最好O(n)初始有序,只需遍历无需移动
平均O(n^2)需要约 n^2/4 次比较和移动
最坏O(n^2)逆序时需要 n^2/2 次操作
空间复杂度O(1)只需要常数级额外空间


标签: js 打印

相关文章

家长看过来 CSP-J/S第一轮认证报名指南

学习信息学的孩子们对于CSP-J/S肯定不会陌生,这项赛事每年都有众多选手参加。对于第一次参赛的孩子来说,如果有不了解的,这篇文章一定要认真看完,对于报名有详细的介绍。报名步骤登录NOI报名系统—新用...

TCT亚洲展:3D打印在骨板设计中的应用

【中关村在线办公打印频道原创】近年来随着3D打印普及越来越广泛,许多行业逐渐出现3D打印机的身影。3D打印无处不在,除了每次出现都能见证奇迹外,3D打印也为许多行业带来了福音,如医疗领域就是最大的受益...

富士施乐S1810 2011 2110 2520 2320等机型网络打印设置教程

设置步骤如下:1、长按“登录”按钮,进入管理员模式2、输入“11111”,点击“启动”3、输入“P1008”,点击两次“启动”,输入“16”,点击“启动”4、用“C”清除以下设置打印机IP地址:192...

你知道 3D 打印技术有多神奇吗?来看看这几款产品你就知道了

什么是 3D 打印?它是快速成型的一种,以数字模型文件为基础,运用粉末状金属或塑料等可粘合材料,通过逐层打印的方式来构造物体的技术。而 3D 打印通常是采用数字技术材料打印机来实现的。之前设计癖介绍过...

保时捷用3D打印制造了一套活塞,可使发动机功率再被压榨出30马力

记者 | 周纯粼编辑 | 汽车制造商们正在积极尝试将3D打印技术应用于制造各种汽车零部件,从简单的内饰件到刹车卡钳这样复杂的零部件都已经能被实现。眼下,保时捷正在尝试3D打印发动机内部零件,让这项技术...

知道树脂和长丝3D打印哪一种更适合你使用吗

有两种主要的材料是用于3D打印的,一种是液体树脂,一种热塑性长丝。熔融沉积成型的(FDM)使用长丝,光固化成型的使用树脂。可以通过以下几个方面来判断你适合使用哪种3D打印技术。  质量  在质量方面,...

发表评论    

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。