当前位置: 首页 > news >正文

深入浅出:插入排序算法完全解析

1. 什么是插入排序?

插入排序(Insertion Sort)是一种简单的排序算法,其基本思想与我们整理扑克牌的方式非常相似。我们将扑克牌从第二张开始依次与前面已排序的牌进行比较,将其插入到合适的位置,直到所有牌都有序。

插入排序是一种逐步构建有序序列的算法,每次从未排序部分中取出一个元素,并将其插入到已排序部分的合适位置。

2. 插入排序的基本思想

插入排序的基本思想是逐步构建一个有序的序列。它将数组分为两部分:已排序部分和未排序部分。每次将未排序部分的第一个元素插入到已排序部分的合适位置,直到整个数组有序。

插入排序的具体步骤:

  1. 将第一个元素看作已排序的部分。
  2. 从第二个元素开始,将当前元素与已排序部分的元素进行比较。
  3. 如果当前元素小于已排序部分的元素,则将已排序部分的元素向右移动一个位置,为当前元素腾出空间。
  4. 将当前元素插入到合适的位置。
  5. 重复步骤2到步骤4,直到所有元素都插入到正确的位置。

插入排序的过程可以通过下面的动画来帮助理解:

假设我们有以下无序数组:

[5, 2, 9, 1, 5, 6]

插入排序的过程如下:

  1. 初始状态:[5, 2, 9, 1, 5, 6]
  2. 插入第二个元素 2:[2, 5, 9, 1, 5, 6]
  3. 插入第三个元素 9:[2, 5, 9, 1, 5, 6]
  4. 插入第四个元素 1:[1, 2, 5, 9, 5, 6]
  5. 插入第五个元素 5:[1, 2, 5, 5, 9, 6]
  6. 插入第六个元素 6:[1, 2, 5, 5, 6, 9]

最终排序后的数组:[1, 2, 5, 5, 6, 9]

3. 插入排序的伪代码

for i = 1 to n-1:          // 从第二个元素开始current = arr[i]       // 当前元素j = i - 1              // 已排序部分的最后一个元素while j >= 0 and arr[j] > current:   // 逐步向前查找插入位置arr[j + 1] = arr[j]                // 将大于当前元素的值向右移动j -= 1arr[j + 1] = current    // 将当前元素插入合适位置

过程说明:

  • 外循环for i = 1 to n-1):从第二个元素开始,逐步将当前元素插入到已排序的部分。
  • 内循环while j >= 0 and arr[j] > current):比较当前元素与已排序部分的元素,并将大于当前元素的元素向右移动。
  • 插入操作:在找到合适位置后,将当前元素插入到空位置。

4. 插入排序的时间复杂度分析

插入排序的时间复杂度取决于输入数据的顺序。

  • 最优情况(已经排好序):每次比较时都无需移动元素,只进行一次比较。此时时间复杂度为 O(n)
  • 最坏情况(完全逆序):每个元素都需要与已排序部分的每个元素进行比较并移动。因此,时间复杂度为 O(n²)
  • 平均情况:假设数据是随机排列的,插入排序的平均时间复杂度也是 O(n²)

空间复杂度:

插入排序只使用常数级的额外空间(只需一个临时变量来保存当前元素),因此它的空间复杂度是 O(1)

总结:

  • 最佳时间复杂度:O(n),当输入数组已经有序时。
  • 最坏时间复杂度:O(n²),当输入数组完全逆序时。
  • 平均时间复杂度:O(n²),适用于随机排列的数据。
  • 空间复杂度:O(1),是一个原地排序算法。

5. 插入排序的优缺点

优点:

  1. 简单易懂:插入排序的算法实现非常简单,适合用来讲解排序的基本思想。
  2. 空间复杂度低:它是原地排序算法,不需要额外的空间(只需常数级别的空间)。
  3. 适用于小数据量:当数据量较小或数据已经部分有序时,插入排序的效率较高。
  4. 稳定排序:插入排序是一种稳定排序算法,意思是相等的元素不会交换位置,保留原有的顺序。

缺点:

  1. 时间复杂度高:对于大数据量的排序,时间复杂度为 O(n²),性能较差,不适合大规模数据的排序。
  2. 不适用于大数据集:对于大规模数据,插入排序会表现得很慢,通常选择更高效的排序算法,如快速排序、归并排序等。

6. 插入排序的代码实现(Java)

Java 实现:

import java.util.Arrays;public class InsertionSort {public static void insertionSort(int[] arr) {// 从第二个元素开始for (int i = 1; i < arr.length; i++) {int current = arr[i];    // 当前元素int j = i - 1;           // 已排序部分的最后一个元素// 查找插入位置while (j >= 0 && arr[j] > current) {arr[j + 1] = arr[j];  // 将大于当前元素的值向右移动j--;}arr[j + 1] = current;    // 插入当前元素}}public static void main(String[] args) {int[] arr = { 5, 2, 9, 1, 5, 6 };System.out.println("Before sorting: " + Arrays.toString(arr));insertionSort(arr);System.out.println("After sorting: " + Arrays.toString(arr));}
}

输出:

Before sorting: [5, 2, 9, 1, 5, 6]
After sorting: [1, 2, 5, 5, 6, 9]

代码解析:

  1. 初始化:从数组的第二个元素开始,假设第一个元素已经是有序的。
  2. 查找插入位置:通过 while 循环,逐步将当前元素与已排序部分的元素进行比较,并向右移动大于当前元素的元素。
  3. 插入当前元素:找到正确的插入位置后,将当前元素插入到该位置。

7. 应用场景

  • 小规模数据:当数据量较小或基本有序时,插入排序非常高效。由于它的时间复杂度较低(O(n))在数据已经排序的情况下,插入排序会比其他复杂的排序算法(如快速排序)更快。
  • 实时数据:插入排序适用于不断接收数据并需要立即排序的场景,例如在实时系统中,插入新数据时只需将数据插入到已排序的部分。
  • 链表排序:对于链表结构,插入排序比其他排序算法(如快速排序)更有效,因为链表本身在插入操作时更为高效。

8. 总结

插入排序是一种简单而有效的排序算法,适用于数据量较小或已经部分有序的情况。它的时间复杂度是 O(n²),因此在处理大规模数据时并不高效,但它是稳定的排序算法,并且实现非常简单。理解插入排序的过程和代码可以帮助我们更好地理解其他排序算法的实现和优化。

相关文章:

深入浅出:插入排序算法完全解析

1. 什么是插入排序&#xff1f; 插入排序&#xff08;Insertion Sort&#xff09;是一种简单的排序算法&#xff0c;其基本思想与我们整理扑克牌的方式非常相似。我们将扑克牌从第二张开始依次与前面已排序的牌进行比较&#xff0c;将其插入到合适的位置&#xff0c;直到所有牌…...

【Keras图像处理入门:图像加载与预处理全解析】

本文将全面讲解如何使用Keras进行图像加载、预处理和数据增强&#xff0c;为深度学习模型准备高质量的图像数据。 一、单张图像处理基础 1. 图像加载与尺寸调整 from keras.preprocessing import image# 加载图像并调整尺寸 img image.load_img(example.jpg, target_size(1…...

企业级AI办公落地实践:基于钉钉/飞书的标准产品解决方案

一、平台化AI的崛起&#xff1a;开箱即用的智能革命 2024年企业AI应用调研数据显示&#xff1a; 73%的中型企业选择平台标准产品而非自研头部SaaS平台AI功能渗透率达89%典型ROI周期从18个月缩短至3-6个月 核心优势对比&#xff1a; 维度自研方案平台标准产品部署周期6-12个…...

对于邮箱地址而言,短中划线(Hyphen, -)和长中划线(Em dash, —)有区别吗

对于邮箱地址而言&#xff0c;**短中划线&#xff08;Hyphen, -&#xff09;和长中划线&#xff08;Em dash, —&#xff09;**有明确的区别&#xff1a; 短中划线&#xff08;Hyphen, -&#xff09;&#xff1a; 在邮箱地址中&#xff0c;短中划线是可以使用的&#xff0c;通常…...

C++ STL(三)list

目录 list是什么 构造函数 元素访问 容量操作 修改 迭代器 code实例 实现简单的list forward_list是什么 构造函数 元素访问 容量 修改 迭代器 code实例 实现一个简单的forward_list list是什么 std::list 是 C 标准模板库&#xff08;STL&#xff09;中的一个…...

Vue3+TypeScript 封装一个好用的防抖节流自定义指令

一、前言&#xff1a;为什么需要防抖节流&#xff1f; 在前端开发中&#xff0c;高频触发的事件&#xff08;如滚动、输入、点击等&#xff09;容易导致性能问题。防抖&#xff08;debounce&#xff09; 和 节流&#xff08;throttle&#xff09; 是两种常用的优化手段&#x…...

HarmonyOS+Django实现图片上传

话不多说&#xff0c;直接看代码&#xff1a; HarmonyOS部分代码 import { router } from "kit.ArkUI" import PreferencesUtil from "../utils/PreferencesUtil" import { photoAccessHelper } from "kit.MediaLibraryKit" import fs from oh…...

vscode 版本

vscode官网 Visual Studio Code - Code Editing. Redefined 但是官网只提供最新 在之前的版本就要去github找了 https://github.com/microsoft/vscode/releases 获取旧版本vscode安装包的方法_vscode 老版本-CSDN博客...

Python 爬虫实战案例 - 获取拉勾网招聘职位信息

引言 拉勾网&#xff0c;作为互联网招聘领域的佼佼者&#xff0c;汇聚了海量且多样的职位招聘信息。这些信息涵盖了从新兴科技领域到传统行业转型所需的各类岗位&#xff0c;无论是初出茅庐的应届生&#xff0c;还是经验丰富的职场老手&#xff0c;都能在其中探寻到机遇。 对…...

结构型模式---外观模式

概念 外观模式是一种结构型设计模式&#xff0c;它的核心思想是为复杂的子系统提供一个统一的接口&#xff0c;简化客户端与子系统的交互。外观模式通过引入一个高层接口&#xff0c;隐藏子系统的复杂性&#xff0c;使客户端更容易使用。 适用场景 用于客户端无需具体操作子…...

Docker数据卷操作实战

什么是数据卷 数据卷 是一个可供一个或多个容器使用的特殊目录&#xff0c;它绕过 UFS&#xff0c;可以提供很多有用的特性: 数据卷 可以在容器之间共享和享用对 数据卷 的修改立马生效对 数据卷 的更新&#xff0c;不会影响镜像数据卷 默认会一直存在&#xff0c;即时容器被…...

技术速递|Copilot Usage Advanced Dashboard 教程

作者&#xff1a;Xuefeng Yin 排版&#xff1a;Alan Wang Copilot Usage Advanced Dashboard 是为了充分利用 GitHub Copilot API 中的几乎所有数据&#xff0c;用到的 API 有&#xff1a; List teams of an onganization Get a summary of Copilot metrics for a team Get C…...

【Python爬虫(90)】以Python爬虫为眼,洞察金融科技监管风云

【Python爬虫】专栏简介:本专栏是 Python 爬虫领域的集大成之作,共 100 章节。从 Python 基础语法、爬虫入门知识讲起,深入探讨反爬虫、多线程、分布式等进阶技术。以大量实例为支撑,覆盖网页、图片、音频等各类数据爬取,还涉及数据处理与分析。无论是新手小白还是进阶开发…...

Shell学习(1/6) 教程-变量

一、教程 Shell 是一个用 C 语言编写的程序&#xff0c;它是用户使用 Linux 的桥梁。Shell 既是一种命令语言&#xff0c;又是一种程序设计语言。 Shell 是指一种应用程序&#xff0c;这个应用程序提供了一个界面&#xff0c;用户通过这个界面访问操作系统内核的服务。 Shell…...

《Qt窗口动画实战:Qt实现呼吸灯效果》

Qt窗口动画实战&#xff1a;Qt实现呼吸灯效果 在嵌入式设备或桌面应用中&#xff0c;呼吸灯效果是一种常见且优雅的UI动画&#xff0c;常用于指示系统状态或吸引用户注意。本文将介绍如何使用Qt动画框架实现平滑的呼吸灯效果。 一、实现原理 利用Qt自带的动画框架来实现&…...

RabbitMQ系列(六)基本概念之Routing Key

在 RabbitMQ 中&#xff0c;Routing Key&#xff08;路由键&#xff09; 是用于将消息从交换机&#xff08;Exchange&#xff09;路由到指定队列&#xff08;Queue&#xff09;的关键参数。其核心作用是通过特定规则匹配绑定关系&#xff0c;确保消息被正确分发。以下是其核心机…...

Spring Boot 集成 Kafka

在现代软件开发中&#xff0c;分布式系统和微服务架构越来越受到关注。为了实现系统之间的异步通信和解耦&#xff0c;消息队列成为了一种重要的技术手段。Kafka 作为一种高性能、分布式的消息队列系统&#xff0c;被广泛应用于各种场景。而 Spring Boot 作为一种流行的 Java 开…...

CentOS中shell脚本对多台机器执行下载安装

1.建立免密ssh连接 详情见这篇&#xff1a; CentOS建立ssh免密连接&#xff08;含流程剖析&#xff09;-CSDN博客 2.脚本编写 我这里只是简单写了个demo进行演示&#xff0c;如果服务器很多可以先暂存成文件再逐行读取host进行连接并执行命令 用node1去ssh连接node2和node…...

浅析eBPF

目录 一、eBPF 原理 二、eBPF 已可投入使用的场景 三、eBPF 与 Jaeger/Zipkin 的区别及先进性 四、使用 eBPF 的开源软件 五、开源软件的局限性或待实现功能 猫哥说 一、eBPF 原理 eBPF (extended Berkeley Packet Filter) 是一种内核技术&#xff0c;允许用户在内核空间…...

HTML 基础 (快速入门)详细步骤和示例

目录 创建基本的 HTML 文件 添加内容到页面 页面布局与链接 HTML&#xff08;超文本标记语言&#xff09;是构建网页的基础技术&#xff0c;以下是 HTML 基础的详细步骤和示例&#xff1a; 创建基本的 HTML 文件 步骤一&#xff1a;新建文件 在本地计算机上选择一个合适的…...

网络编程(Modbus进阶)

思维导图 Modbus RTU&#xff08;先学一点理论&#xff09; 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议&#xff0c;由 Modicon 公司&#xff08;现施耐德电气&#xff09;于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...

day52 ResNet18 CBAM

在深度学习的旅程中&#xff0c;我们不断探索如何提升模型的性能。今天&#xff0c;我将分享我在 ResNet18 模型中插入 CBAM&#xff08;Convolutional Block Attention Module&#xff09;模块&#xff0c;并采用分阶段微调策略的实践过程。通过这个过程&#xff0c;我不仅提升…...

转转集团旗下首家二手多品类循环仓店“超级转转”开业

6月9日&#xff0c;国内领先的循环经济企业转转集团旗下首家二手多品类循环仓店“超级转转”正式开业。 转转集团创始人兼CEO黄炜、转转循环时尚发起人朱珠、转转集团COO兼红布林CEO胡伟琨、王府井集团副总裁祝捷等出席了开业剪彩仪式。 据「TMT星球」了解&#xff0c;“超级…...

Java入门学习详细版(一)

大家好&#xff0c;Java 学习是一个系统学习的过程&#xff0c;核心原则就是“理论 实践 坚持”&#xff0c;并且需循序渐进&#xff0c;不可过于着急&#xff0c;本篇文章推出的这份详细入门学习资料将带大家从零基础开始&#xff0c;逐步掌握 Java 的核心概念和编程技能。 …...

GC1808高性能24位立体声音频ADC芯片解析

1. 芯片概述 GC1808是一款24位立体声音频模数转换器&#xff08;ADC&#xff09;&#xff0c;支持8kHz~96kHz采样率&#xff0c;集成Δ-Σ调制器、数字抗混叠滤波器和高通滤波器&#xff0c;适用于高保真音频采集场景。 2. 核心特性 高精度&#xff1a;24位分辨率&#xff0c…...

HDFS分布式存储 zookeeper

hadoop介绍 狭义上hadoop是指apache的一款开源软件 用java语言实现开源框架&#xff0c;允许使用简单的变成模型跨计算机对大型集群进行分布式处理&#xff08;1.海量的数据存储 2.海量数据的计算&#xff09;Hadoop核心组件 hdfs&#xff08;分布式文件存储系统&#xff09;&a…...

【VLNs篇】07:NavRL—在动态环境中学习安全飞行

项目内容论文标题NavRL: 在动态环境中学习安全飞行 (NavRL: Learning Safe Flight in Dynamic Environments)核心问题解决无人机在包含静态和动态障碍物的复杂环境中进行安全、高效自主导航的挑战&#xff0c;克服传统方法和现有强化学习方法的局限性。核心算法基于近端策略优化…...

IP如何挑?2025年海外专线IP如何购买?

你花了时间和预算买了IP&#xff0c;结果IP质量不佳&#xff0c;项目效率低下不说&#xff0c;还可能带来莫名的网络问题&#xff0c;是不是太闹心了&#xff1f;尤其是在面对海外专线IP时&#xff0c;到底怎么才能买到适合自己的呢&#xff1f;所以&#xff0c;挑IP绝对是个技…...

处理vxe-table 表尾数据是单独一个接口,表格tableData数据更新后,需要点击两下,表尾才是正确的

修改bug思路&#xff1a; 分别把 tabledata 和 表尾相关数据 console.log() 发现 更新数据先后顺序不对 settimeout延迟查询表格接口 ——测试可行 升级↑&#xff1a;async await 等接口返回后再开始下一个接口查询 ________________________________________________________…...

32单片机——基本定时器

STM32F103有众多的定时器&#xff0c;其中包括2个基本定时器&#xff08;TIM6和TIM7&#xff09;、4个通用定时器&#xff08;TIM2~TIM5&#xff09;、2个高级控制定时器&#xff08;TIM1和TIM8&#xff09;&#xff0c;这些定时器彼此完全独立&#xff0c;不共享任何资源 1、定…...