百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术分类 > 正文

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

ztj100 2025-04-29 06:57 4 浏览 0 评论

一、插入排序概念

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)只需要常数级额外空间


相关推荐

如何将数据仓库迁移到阿里云 AnalyticDB for PostgreSQL

阿里云AnalyticDBforPostgreSQL(以下简称ADBPG,即原HybridDBforPostgreSQL)为基于PostgreSQL内核的MPP架构的实时数据仓库服务,可以...

Python数据分析:探索性分析

写在前面如果你忘记了前面的文章,可以看看加深印象:Python数据处理...

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

...

C++基础语法梳理:算法丨十大排序算法(二)

本期是C++基础语法分享的第十六节,今天给大家来梳理一下十大排序算法后五个!归并排序...

C 语言的标准库有哪些

C语言的标准库并不是一个单一的实体,而是由一系列头文件(headerfiles)组成的集合。每个头文件声明了一组相关的函数、宏、类型和常量。程序员通过在代码中使用#include<...

[深度学习] ncnn安装和调用基础教程

1介绍ncnn是腾讯开发的一个为手机端极致优化的高性能神经网络前向计算框架,无第三方依赖,跨平台,但是通常都需要protobuf和opencv。ncnn目前已在腾讯多款应用中使用,如QQ,Qzon...

用rust实现经典的冒泡排序和快速排序

1.假设待排序数组如下letmutarr=[5,3,8,4,2,7,1];...

ncnn+PPYOLOv2首次结合!全网最详细代码解读来了

编辑:好困LRS【新智元导读】今天给大家安利一个宝藏仓库miemiedetection,该仓库集合了PPYOLO、PPYOLOv2、PPYOLOE三个算法pytorch实现三合一,其中的PPYOL...

C++特性使用建议

1.引用参数使用引用替代指针且所有不变的引用参数必须加上const。在C语言中,如果函数需要修改变量的值,参数必须为指针,如...

Qt4/5升级到Qt6吐血经验总结V202308

00:直观总结增加了很多轮子,同时原有模块拆分的也更细致,估计为了方便拓展个管理。把一些过度封装的东西移除了(比如同样的功能有多个函数),保证了只有一个函数执行该功能。把一些Qt5中兼容Qt4的方法废...

到底什么是C++11新特性,请看下文

C++11是一个比较大的更新,引入了很多新特性,以下是对这些特性的详细解释,帮助您快速理解C++11的内容1.自动类型推导(auto和decltype)...

掌握C++11这些特性,代码简洁性、安全性和性能轻松跃升!

C++11(又称C++0x)是C++编程语言的一次重大更新,引入了许多新特性,显著提升了代码简洁性、安全性和性能。以下是主要特性的分类介绍及示例:一、核心语言特性1.自动类型推导(auto)编译器自...

经典算法——凸包算法

凸包算法(ConvexHull)一、概念与问题描述凸包是指在平面上给定一组点,找到包含这些点的最小面积或最小周长的凸多边形。这个多边形没有任何内凹部分,即从一个多边形内的任意一点画一条线到多边形边界...

一起学习c++11——c++11中的新增的容器

c++11新增的容器1:array当时的初衷是希望提供一个在栈上分配的,定长数组,而且可以使用stl中的模板算法。array的用法如下:#include<string>#includ...

C++ 编程中的一些最佳实践

1.遵循代码简洁原则尽量避免冗余代码,通过模块化设计、清晰的命名和良好的结构,让代码更易于阅读和维护...

取消回复欢迎 发表评论: