当前位置: 首页 > 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;新建文件 在本地计算机上选择一个合适的…...

C++实现分布式网络通信框架RPC(3)--rpc调用端

目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中&#xff0c;我们已经大致实现了rpc服务端的各项功能代…...

iOS 26 携众系统重磅更新,但“苹果智能”仍与国行无缘

美国西海岸的夏天&#xff0c;再次被苹果点燃。一年一度的全球开发者大会 WWDC25 如期而至&#xff0c;这不仅是开发者的盛宴&#xff0c;更是全球数亿苹果用户翘首以盼的科技春晚。今年&#xff0c;苹果依旧为我们带来了全家桶式的系统更新&#xff0c;包括 iOS 26、iPadOS 26…...

<6>-MySQL表的增删查改

目录 一&#xff0c;create&#xff08;创建表&#xff09; 二&#xff0c;retrieve&#xff08;查询表&#xff09; 1&#xff0c;select列 2&#xff0c;where条件 三&#xff0c;update&#xff08;更新表&#xff09; 四&#xff0c;delete&#xff08;删除表&#xf…...

【人工智能】神经网络的优化器optimizer(二):Adagrad自适应学习率优化器

一.自适应梯度算法Adagrad概述 Adagrad&#xff08;Adaptive Gradient Algorithm&#xff09;是一种自适应学习率的优化算法&#xff0c;由Duchi等人在2011年提出。其核心思想是针对不同参数自动调整学习率&#xff0c;适合处理稀疏数据和不同参数梯度差异较大的场景。Adagrad通…...

使用分级同态加密防御梯度泄漏

抽象 联邦学习 &#xff08;FL&#xff09; 支持跨分布式客户端进行协作模型训练&#xff0c;而无需共享原始数据&#xff0c;这使其成为在互联和自动驾驶汽车 &#xff08;CAV&#xff09; 等领域保护隐私的机器学习的一种很有前途的方法。然而&#xff0c;最近的研究表明&…...

(二)原型模式

原型的功能是将一个已经存在的对象作为源目标,其余对象都是通过这个源目标创建。发挥复制的作用就是原型模式的核心思想。 一、源型模式的定义 原型模式是指第二次创建对象可以通过复制已经存在的原型对象来实现,忽略对象创建过程中的其它细节。 📌 核心特点: 避免重复初…...

数据链路层的主要功能是什么

数据链路层&#xff08;OSI模型第2层&#xff09;的核心功能是在相邻网络节点&#xff08;如交换机、主机&#xff09;间提供可靠的数据帧传输服务&#xff0c;主要职责包括&#xff1a; &#x1f511; 核心功能详解&#xff1a; 帧封装与解封装 封装&#xff1a; 将网络层下发…...

今日学习:Spring线程池|并发修改异常|链路丢失|登录续期|VIP过期策略|数值类缓存

文章目录 优雅版线程池ThreadPoolTaskExecutor和ThreadPoolTaskExecutor的装饰器并发修改异常并发修改异常简介实现机制设计原因及意义 使用线程池造成的链路丢失问题线程池导致的链路丢失问题发生原因 常见解决方法更好的解决方法设计精妙之处 登录续期登录续期常见实现方式特…...

【生成模型】视频生成论文调研

工作清单 上游应用方向&#xff1a;控制、速度、时长、高动态、多主体驱动 类型工作基础模型WAN / WAN-VACE / HunyuanVideo控制条件轨迹控制ATI~镜头控制ReCamMaster~多主体驱动Phantom~音频驱动Let Them Talk: Audio-Driven Multi-Person Conversational Video Generation速…...

七、数据库的完整性

七、数据库的完整性 主要内容 7.1 数据库的完整性概述 7.2 实体完整性 7.3 参照完整性 7.4 用户定义的完整性 7.5 触发器 7.6 SQL Server中数据库完整性的实现 7.7 小结 7.1 数据库的完整性概述 数据库完整性的含义 正确性 指数据的合法性 有效性 指数据是否属于所定…...