【保姆级图解】插入排序 算法详解:直接插入排序、希尔排序

 总体引入

在计算机科学的算法领域中,排序是一项基础且重要的操作。它旨在将一组无序的数据元素重新排列为有序序列,以满足特定的顺序要求,如升序或降序。常见的排序算法可分为不同类别,像插入排序,包含直接插入排序和希尔排序;选择排序,有直接选择排序和堆排序;交换排序,涵盖冒泡排序和快速排序;还有归并排序 。这些算法各有特点,适用于不同的应用场景,接下来让我们深入了解它们。

 

插入排序引入

想象你整理扑克牌时,会从一堆牌里一张一张拿出来,按顺序插到已经整理好的牌堆合适位置 。编程里的插入排序差不多也是这个道理。它把数据分成已排序和未排序两部分,从 未排序部分取元素,在已排序部分找到合适位置插入,不断重复,直到所有元素都排好序,就像把乱序的扑克牌整理成有序的一样。

一、直接插入排序(Insertion Sort)

算法思想
将数组分为“已排序”和“未排序”两部分,逐个将未排序部分的元素插入到已排序部分的正确位置。

代码解析

void InsertSort(int* arr, int n) {for (int i = 0; i < n - 1; i++) {  // 从第一个元素开始遍历到倒数第二个元素int end = i;                   // 已排序部分的末尾索引int tmp = arr[end + 1];        // 待插入元素(未排序部分的第一个元素)while (end >= 0) {             // 向前寻找插入位置if (arr[end] > tmp) {      // 若当前元素大于待插入元素,则后移arr[end + 1] = arr[end];end--;} else {                   // 找到合适位置,退出循环break;}}arr[end + 1] = tmp;            // 插入元素到正确位置}
}

步骤说明

  1. 外层循环:遍历每个待插入元素(从第二个元素开始)。

  2. 内层循环:从后向前比较,若当前元素比待插入元素大,则将其后移。

  3. 插入操作:找到第一个比待插入元素小的位置,将元素插入其后。

复杂度分析

  • 时间复杂度:

    • 最好情况(已有序):O(n),只需比较无需移动。

    • 最坏情况(逆序):O(n²),每次插入需移动全部已排序元素。

  • 空间复杂度:O(1),原地排序。

适用场景
数据量小或基本有序时效率高,稳定且简单。


二、希尔排序(Shell Sort)

算法思想
希尔排序是对直接插入排序的一种改进算法,它通过将待排序的数组按照一定的间隔(称为增量)进行分组,对每组分别进行直接插入排序,逐步缩小增量,当 gap > 1 时都是预排序,⽬的是让数组更接近于有序。当 gap == 1 时,数组已经接近有序的了,这样就会很快。这样整体⽽⾔,可以达到优化的效果。

代码解析

void ShellSort(int* arr, int n) {int gap = n;                       // 初始间隔设为数组长度while (gap > 1) {                  // 循环直到间隔为1(最后一次完整插入排序)gap = gap / 3 + 1;            // 动态调整间隔(常见增量方式)for (int i = 0; i < n - gap; i++) {  // 对所有间隔分组进行插入排序int end = i;               // 当前组的已排序末尾int tmp = arr[end + gap]; // 待插入元素while (end >= 0) {        // 组内插入排序if (arr[end] > tmp) {  arr[end + gap] = arr[end];end -= gap;        // 跨间隔移动} else {break;}}arr[end + gap] = tmp;      // 插入元素}}
}

步骤说明

  1. 动态调整间隔:初始间隔较大,逐步缩小(gap = gap/3 + 1)或者(gap = gap/2)

  2. 分组插入排序:对每个间隔形成的子序列进行插入排序。

  3. 最终排序:当间隔为1时,退化为标准插入排序,此时数组已基本有序。

复杂度分析

  • 时间复杂度:约 O(n^1.3),依赖增量序列的选择。

  • 空间复杂度:O(1),原地排序。

适用场景
中等规模数据,对稳定性无要求,优于直接插入排序。


测试案例
void test01() {int arr[] = {9, 8, 7, 6, 5, 4, 3, 2, 1, 0};int size = sizeof(arr) / sizeof(arr[0]);// InsertSort(arr, size);ShellSort(arr, size);for (int i = 0; i < size; i++) {printf("%d ", arr[i]);  // 输出:0 1 2 3 4 5 6 7 8 9}
}

运行结果
无论调用哪个排序函数,最终输出均为有序数组 0 1 2 3 4 5 6 7 8 9


总结
  • 直接插入排序:简单稳定,适合小数据或部分有序场景。

  • 希尔排序:插入排序的高效改进,适合中等规模数据。

理解基础排序算法的实现有助于掌握更复杂的排序技术,实际应用中可根据数据特征选择合适的算法。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/75296.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

为什么ChatGPT选择SSE而非WebSocket?

为什么ChatGPT选择SSE而非WebSocket&#xff1f; 一、ChatGPT回答问题的技术逻辑 ChatGPT的响应生成基于Transformer架构和自注意力机制&#xff0c;其核心是通过概率预测逐词生成文本。当用户输入问题后&#xff0c;模型会先解析上下文&#xff0c;再通过预训练的庞大语料库…

Android 手机指纹传感器无法工作,如何恢复数据?

天津鸿萌科贸发展有限公司从事数据安全服务二十余年&#xff0c;致力于为各领域客户提供专业的数据恢复、数据清除、数据备份、数据取证、数据迁移解决方案&#xff0c;并针对企业面临的数据安全风险&#xff0c;提供专业的相关数据安全培训。 天津鸿萌科贸发展有限公司是众多国…

DeepSeek 在金融领域的应用解决方案

DeepSeek 在金融领域的应用解决方案 一、背景 随着人工智能技术的快速发展&#xff0c;DeepSeek 作为一款国产大模型&#xff0c;凭借其强大的语义理解、逻辑推理和多模态处理能力&#xff0c;在金融行业迅速崭露头角。金融行业作为经济的核心&#xff0c;面临着激烈的市场竞…

织光五载 焕新启航

成都时尚产业协会5周年 以创新为笔&#xff0c;续写国际时尚之都的璀璨篇章 【一场跨越时空的时尚对话】 五年前&#xff0c;一颗名为"成都时尚产业协会"的种子在蓉城落地生根&#xff1b;五年后&#xff0c;这棵新芽已成长为枝繁叶茂的生态之树&#xff0c;用交织…

scala集合

一、数组&#xff08;Array&#xff09; 1.数组转换 不可变转可变&#xff1a;arr1.toBuffer&#xff0c;arr1本身没有变化 可变转不可变&#xff1a;arr2.toArray&#xff0c;arr2本身没有变化 2.多维数组 创建&#xff1a;val arr Array.ofDim[Int](3, 4)&#xff08;3 …

常用 Excel VBA 技巧,简单好学易上手

在日常办公中&#xff0c;我们常常会遇到各种繁琐的数据处理任务&#xff0c;而 Excel VBA&#xff08;Visual Basic for Applications&#xff09;作为一款强大的自动化工具&#xff0c;能够帮助我们轻松应对这些挑战。本文将介绍一些常用且简单好学的 Excel VBA 技巧&#xf…

Java 基础 - 反射(1)

文章目录 引入类加载过程1. 通过 new 创建对象2. 通过反射创建对象2.1 触发加载但不初始化2.2 按需触发初始化2.3 选择性初始化控制 核心用法示例1. 通过无参构造函数创建实例对象2. 通过有参构造函数创建实例对象3. 反射通过私有构造函数创建对象&#xff0c; 破坏单例模式4. …

如何在React中集成 PDF.js?构建支持打印下载的PDF阅读器详解

本文深入解析基于 React 和 PDF.js 构建 PDF 查看器的实现方案&#xff0c;该组件支持 PDF 渲染、图片打印和下载功能&#xff0c;并包含完整的加载状态与错误处理机制。 完整代码在最后 一个PDF 文件&#xff1a; https://mozilla.github.io/pdf.js/web/compressed.tracemo…

数据结构与算法-动态规划-线性动态规划,0-1背包,多重背包,完全背包,有依赖的背包,分组背包,背包计数,背包路径

动态规划原理 动态规划这玩意儿&#xff0c;就好比是在拓扑图上玩跳格子游戏。在图论中&#xff0c;咱们是从特定的节点跳到其他节点&#xff1b;而在动态规划里呢&#xff0c;我们是从一个状态 “嗖” 地转移到另一个状态。状态一般用数组来表示&#xff0c;就像 f [i][j]&am…

解决文件夹解压中文字符产生乱码的问题

太tm智能了&#xff0c;本来还想看看解压工具在哪里修改&#xff0c;智能的识别到乱码了。点赞 看到那个地球了吗&#xff0c;点击那个球&#xff0c;这个修改不是侵略性的&#xff0c;不会修改压缩文件本身所以需要在当前页面解压 参考 https://blog.csdn.net/QCSYSZQ/artic…

C++与C的区别

目录 前言 一、从字面上看 二、从编程思想上看 三、C 和 C++ 都有各自适合的领域和特性 四、划重点 前言 本文主要对 C 和 C++ 两种编程语言进行对比区分,便于大家理解 一、从字面上看 1.首先:两者第一个字符完全一致 说明:C++ 完全兼容 C ,凡是合法的 C 程序在 C…

水利水电安全员ABC适合哪些人考?

水利水电安全员证是水利工程建设领域的重要职业资格证书&#xff0c;主要涉及水利水电工程施工安全管理、风险防控和应急处理等工作。那么&#xff0c;哪些人适合考取&#xff1f; 哪些人适合考水利水电安全员&#xff1f; 1. 水利水电工程从业人员 ✅ 施工管理人员&#xf…

Linux中用gdb查看coredump文件

查看dump的命令&#xff1a; gdb 可执行文件 dump文件路径查看函数调用栈 (gdb)bt查看反汇编代码 (gdb)disassemble查看寄存器的值 (gdb)info all-registers如果通过上述简单命令无法排查&#xff0c;还是通过-g参数编译带符号表的可执行文件&#xff0c;再用gdb查看

【前端】【React】useCallback的作用与使用场景总结

一、useCallback 的作用与使用场景总结 useCallback 是 React 提供的一个 Hook&#xff0c;用于缓存函数的引用&#xff0c;避免因为组件重新渲染而导致函数地址发生变化。它返回一个记忆&#xff08;memoized&#xff09;后的回调函数&#xff0c;只有当依赖项发生变化时才会…

蓝桥杯备赛学习笔记:高频考点与真题预测(C++/Java/python版)

2025蓝桥杯备赛学习笔记 ——高频考点与真题预测 一、考察趋势分析 通过对第13-15届蓝桥杯真题的分析&#xff0c;可以发现题目主要围绕基础算法、数据结构、数学问题、字符串处理、编程语言基础展开&#xff0c;且近年逐渐增加动态规划、图论、贪心算法等较难题目。 1. 基…

20250410在荣品的PRO-RK3566开发板使用Rockchip原厂的buildroot系统时自动挂载eth0【直接编译进IMG】

【暂时没有找到第一次编译就可以修改的地方&#xff01;&#xff01;&#xff01;&#xff01;】 rootrootrootroot-X99-Turbo:~/RK3566_RK3568_Linux5.10_V1.2.0$ find . -name interfaces 【完整编译之后&#xff0c;基本确认修改这里有效。】 ./buildroot/output/rockchip_r…

c11新特性,继承构造函数

#include <iostream> #include <string>class Person { public:std::string name;int age;// 主构造函数Person(const std::string& name, int age) : name(name), age(age) {std::cout << "Person created with name: " << name <&l…

【TS学习】(24)什么是装饰器

在 TypeScript 中&#xff0c;装饰器&#xff08;Decorators&#xff09; 是一种特殊的声明&#xff0c;用于为类、类成员&#xff08;属性、方法、访问器&#xff09;、方法参数或整个类添加元数据或修改其行为。装饰器是 JavaScript 和 TypeScript 的实验性特性&#xff0c;广…

datagrip如何连接数据库

datagrip连接数据库的步骤 2025版本 想要链接数据库是需要一个jar包的&#xff0c;所以将上面进行删除之后&#xff0c;需要下载一个jar包 那么这个时候需要链接上传一个mysql链接的jar包 选择核心驱动类 上述操作完成之后&#xff0c;然后点击apply再点击ok即可 如下图说明my…

菊风RTC 2.0 开发者文档正式发布,解锁音视频新体验!

重磅发布&#xff01; 开发者们&#xff0c;菊风实时音视频2.0文档已正式发布上线&#xff0c;为您提供更清晰、更高效的开发支持&#xff01;让菊风实时音视频2.0为您的音视频应用加速~ 菊风实时音视频2.0聚焦性能升级、体验升级、录制服务升级&#xff0c;助力视频通话、语…