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

boyanx8个月前技术教程47

一、插入排序概念

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报名系统—新用...

JS 对象基本用法

对象object定义无序的数据集合键值对的集合写法let obj = { 'name':'Frank','age':18 } //常用写法 let ob...

一年一度的CSP-J/S报名可以缴费了,手把手教新人报名

2023年度CSP-J/S报名从7月7日开始,就可以注册报名了,值得注意的是CSP-J/S报名系统每年都要重新注册的,去年的注册信息会作废掉。今天已经可以缴费了,看到有些粉丝在咨询报名相关的事情,今天...

projet2500快速成型机

3D Systems 多喷头打印 (MJP) 工艺能够制造出精 密的塑料部件,是功能原型制造、快速模具制造 等多种应用的理想之选。使用类 ABS 塑料和实际 弹性体可打印刚性或柔韧性部件,实现真正的功...

文件打印也要hin时尚 彩激一体机必备

【中关村在线办公打印频道原创】年轻人讲究个时尚,生活要有品质,工作也不不能跌范儿。打印个文件也要hin有范儿,生硬的黑白文档不要,文字线条不够清晰不要,打印文档不洁净不要......看来,办公室需要添...

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

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

发表评论    

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