插入排序:理解经典的排序技术

什么是插入排序?

插入排序是一种简单而直观的排序算法,它的工作方式类似于我们手动排序卡片或整理文件:

工作原理:
初始状态:将数组分为两部分:一部分是已排序的(最开始时这部分只包含第一个元素),另一部分是未排序的(包含数组的其余部分)。

排序过程:

取元素:从未排序的部分取出第一个元素,这个元素在逻辑上是“手中拿着的牌”。
寻找位置:将这个元素与已排序部分的元素从后向前依次比较。
插入动作:如果“手中的牌”比比较的元素小(对于升序排序),则将比较的元素向后移动一位,为插入新元素腾出空间。
放置元素:当找到一个已排序的元素小于或等于“手中的牌”,或者已经比较到了已排序部分的第一个元素时,将“手中的牌”放在这个位置上。
重复过程:重复上述过程,每次将未排序部分的第一个元素插入到已排序部分的正确位置,直到未排序部分没有元素为止。

插入排序的工作原理

让我们通过一个具体的例子来说明插入排序的工作原理:

假设我们有一个未排序的数列 [7, 2, 4, 9, 3],我们希望对其进行升序排序。

  1. 开始排序:最初,我们将第一个元素(7)视为已排序的序列。
  2. 第一轮排序
    • 取出下一个元素(2),与已排序序列(7)从后向前比较。
    • 由于2小于7,我们将7向后移动一位,使得2占据第一个位置。数组变为 [2, 7, 4, 9, 3]
  3. 第二轮排序
    • 取出4,与已排序序列(2, 7)从后向前比较。
    • 4大于2,但小于7,因此我们将7向后移动一位,4插入到7之前。数组变为 [2, 4, 7, 9, 3]
  4. 后续轮次
    • 重复上述过程,每次取出未排序部分的第一个元素,将其插入到已排序序列的正确位置。
  5. 排序完成
    • 经过几轮排序后,整个数组变为有序,最终序列为 [2, 3, 4, 7, 9]

插入排序的代码示例(Python)重点重点重点讲解

代码中的相关注释一定要好好看

def insertion_sort(arr):for i in range(1, len(arr)):key = arr[i]#插入排序是从后往前比较的#当前选中的元素与其前一个比较,如果有序,则不需要调换位置#如果无序,则需要换位置j = i-1 #这一行代码就是去到位置i的前一个元素的位置#当j>=0不用解释,索引不能够为负数
#key是位置j前面的元素,判断a[j]与a[j-1]的大小,如果不是有序的就要调整位置while j >=0 and key < arr[j]:#到了while内部说明不是有序的,需要调整,把大的往后移arr[j+1] = arr[j]j -= 1
#举个例子[2,3,1],1的位置为2,j就应该是2-1=1,检测到2比1小,赋值[2,3,3],这时候j=j-1,j=0,1与2相比还是小,在挪一下
#[2,2,3],到头了,j=-1,说明碰到最坏的情况了移动到头了,但还好排完顺序了,退出whilearr[j+1] = key#刚刚是不是到了[2,2,3],把1放进去[1,2,3],搞定一次排序# 测试数组
arr = [7, 2, 4, 9, 3]
insertion_sort(arr)
print("Sorted array is:", arr)

在这个代码示例中,insertion_sort 函数实现了插入排序算法。它逐一将未排序部分的元素插入到已排序部分的正确位置。

插入排序的时间复杂度

最佳情况 - O(n)

在最佳情况下,即输入数组已经是完全有序的情况下,每个元素无需移动,只需进行一次比较即可确定其位置。

markdownCopy code最佳情况时间复杂度:
- 对于每个元素,仅需进行一次比较。
- 总比较次数 = 1 + 1 + ... + 1 = n 次
- 时间复杂度 = O(n)
平均情况和最坏情况 - O(n^2)

在平均情况或最坏情况(输入数组完全逆序)下,每次插入可能需要在已排序的部分中比较和移动所有元素。

平均情况和最坏情况时间复杂度:
-1个元素需要比较1次,第2个元素最多比较2次,...,第n个元素最多比较n次。
- 总比较次数 = 1 + 2 + 3 + ... + n
- 使用等差数列求和公式:总比较次数 = n * (n + 1) / 2 ≈ n^2 / 2
- 时间复杂度 = O(n^2)

插入排序的空间复杂度

插入排序是一种原地排序算法,不需要额外的存储空间,除了输入数组外,它仅需要一个额外的存储空间来暂存当前要插入的元素。

空间复杂度:
- 需要常数级别的额外空间
- 空间复杂度 = O(1)

插入排序的优势

  1. 简单直观
    • 插入排序的算法非常直接——就像人们整理手中的扑克牌一样,逐一选择元素并将其放置在适当的位置。这种直观性使得插入排序易于理解和实现,特别是对于编程新手而言。
    • 由于其简单性,插入排序经常被用作教学初级排序算法的典型例子。
  2. 适合小数据集
    • 在处理小型数据集时,插入排序可以非常高效,尤其是当输入数组大部分已经排序时。在这种情况下,插入排序的实际性能可以接近 O(n)。
    • 对于较小的数据集,其实现的简单性可能超过了其他更复杂排序算法的微小性能优势。
  3. 稳定排序
    • 插入排序是一种稳定的排序算法,这意味着它会保留相等元素的初始顺序。这在某些应用中是非常重要的,比如当主键相同时保持记录的相对顺序。

插入排序的劣势

  1. 效率较低
    • 对于大规模的数据集,插入排序的效率通常不如其他更高级的排序算法,如快速排序、归并排序或堆排序。这是因为其平均和最坏情况的时间复杂度都是 O(n^2),导致在数据量增大时性能急剧下降。
    • 在最坏的情况下(即输入数组完全逆序),每次插入都可能需要比较和移动所有已排序元素,导致效率极低。
  2. 不适合大规模数据集
    • 当处理大量数据时,插入排序的性能不足可能成为一个严重的缺点。在这种情况下,时间复杂度较低的算法(如 O(n log n))会显著优于插入排序。
    • 对于大数据集,插入排序的大量元素移动操作会导致显著的性能下降。

结语

总的来说,插入排序因其简单性和在特定情况下的高效性而受到欢迎,尤其适用于数据量小或部分有序的数据集。然而,由于其在处理大规模数据集时的性能限制,它通常不适用于更复杂的应用场景,其中可能会选择更高效的排序算法。了解插入排序的这些优势和劣势可以帮助开发者在面对不同的排序需求时作出更合适的算法选择。
下一期讲解希尔排序,相当于升级版插入排序

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

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

相关文章

SVD recommendation systems

SVD recommendation systems 为什么在推荐系统中使用SVD 一个好的推荐系统一定有小的RMSE R M S E 1 m ∑ i 1 m ( Y i − f ( x i ) 2 RMSE \sqrt{\frac{1}{m} \sum_{i1}^m(Y_i-f(x_i)^2} RMSEm1​i1∑m​(Yi​−f(xi​)2 ​ 希望模型能够在已知的ratings上有好的结果的…

[学习笔记]IK分词器的学习

IK分词器有几种模式 # 测试分词器 POST /_analyze {"text":"黑马程序员学习java太棒了","analyzer": "standard" }# 测试分词器 POST /_analyze {"text":"黑马程序员学习java太棒了","analyzer": &quo…

电脑风扇转一下停一下,无法正常开机问题解决

今天同事电话说电脑开不了机了&#xff0c;只听见风扇不停地呜呜地作响。笔者第一反应是不是硬件哪里出问题了&#xff0c;于是二话没说拿起心爱的螺丝刀就闪了过去。 按下电源&#xff0c;确实如电话所述。但感觉风扇并非一直在转&#xff0c;而是时断时续。由于听不大真切&a…

怎么更新BI报表数据?问我就对了

BI大数据分析工具上有大量的BI报表模板&#xff0c;这些模板都是一个个完整的BI报表&#xff0c;只需将数据源更换&#xff0c;立即就能用来分析我们自己的数据。那&#xff0c;BI报表的数据怎么更新&#xff1f;接下来就来说说这事。 目的&#xff1a;更新BI报表数据 工具&a…

第3章 表、栈和队列

前言 本章讨论最简单和最基本的三种数据结构。实际上&#xff0c;每一个有意义的程序都将至少明确使用一种这样的数据结构&#xff0c;而栈则在程序中总是隐含使用&#xff0c;不管你在程序中是否做了声明。 在这一章&#xff0c;我们将&#xff1a; 介绍抽象数据类型…

每日OJ题_算法_双指针⑧力扣18. 四数之和

目录 力扣18. 四数之和 解析代码 力扣18. 四数之和 难度 中等 给你一个由 n 个整数组成的数组 nums &#xff0c;和一个目标值 target 。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[d]] &#xff08;若两个四元组元素一一对应&…

nvm:node版本控制工具

下载安装 首先先下载nvm&#xff0c;下载地址 https://github.com/coreybutler/nvm-windows/releases选择nvm-setup.exe下载即可 常用命令 命令说明nvm list available显示所有可以下载的Node.js版本nvm list显示已安装的版本nvm install 18.12.1安装18.12.1版本的Node.jsnv…

如何把一个数组json数据,加到已有的树形数据中

要将一个数组的 JSON 数据添加到已有的树形数据中&#xff0c;可以使用递归方法遍历树形数据&#xff0c;并将数组中的每个元素插入到合适的位置。以下是一个使用 JavaScript 实现的示例&#xff1a; function insertArrayToTree(tree, arrayData) {if (!tree || !arrayData) …

Pikachu靶场(PHP反序列化漏洞)

查看php反序列化漏洞的概述&#xff0c;了解序列化与反序列化。 构造payload <?php class S{var $test "<script>alert(wjy)</script>"; } $c new S(); echo(serialize($c)); ?>将对象序列化为O:1:"S":1:{s:4:"test";s:…

【Linux下基本指令——(1)】

Linux下基本指令——&#xff08;1&#xff09; 一. ls 指令1.1.语法&#xff1a;1.2.功能&#xff1a;1.3.常用选项&#xff1a;1.4.举例&#xff1a;1.5.Xshell7展示 二. pwd 命令2.1.语法: 2.2.功能&#xff1a;2.3.常用选项&#xff1a;2.4.Xshell7展示 三. cd 指令3.1.语法…

选择跨网数据摆渡系统时,你最关注的功能是哪些?

为什么要选择跨网数据摆渡系统呢&#xff1f;因为做了网络隔离后&#xff0c;要有数据交互。那为什么要做网络隔离呢&#xff1f;主要还是安全方面的考虑&#xff0c;一般有以下几个原因&#xff1a; 1、数据安全保护&#xff1a;对于一些重要数据&#xff0c;比如代码数据、隐…

hutool工具连接数据库实现数据处理重新入库

1 引入依赖 <dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.7.18</version></dependency><!--mysql驱动包--><dependency><groupId>mysql</groupId><ar…

Python语言学习笔记之四(Python文档化)

本课程对于有其它语言基础的开发人员可以参考和学习&#xff0c;同时也是记录下来&#xff0c;为个人学习使用&#xff0c;文档中有此不当之处&#xff0c;请谅解。 Python文档化是指在Python代码中添加注释和文档字符串&#xff0c;以提供有关代码的详细信息和说明。 文档的…

Vue3-admin-template的表格合计计算

直接上代码&#xff1a; <el-table:data"lists"style"width: 100%"max-height"500":header-cell-style"{ textAlign: center }":cell-style"{ textAlign: center }"show-summary:summary-method"getSummaries"…

P24 C++ 字符串常量

前言 本期我们讨论字符串字面量。 这是一种基于字符串的东西&#xff0c;上一章我们讲过字符串&#xff0c;你一定要去先去看看那一期的内容。 P23 C字符串-CSDN博客 01 什么是字符串字常量呢&#xff1f; 字符串字面量就是在双引号之间的一串字符 在上面的代码中&#xf…

Unity针对XBOX,SWITCH,PS5手柄的适配踩坑

前言&#xff1a; 记录一点最近在做手柄适配问题的踩坑。 这里推荐一款Unity做手柄适配的插件->Rewired Rewired官方文档链接Rewired Documentation | Supported Controllers Rewired插件里面有个是Player类&#xff0c;这个类获取到当前玩家的输入设备&#xff0c;输入…

Android:FragmentTransaction

上一篇Android&#xff1a;FragmentTransaction我们大概介绍了FragmentManager的大致工作流程&#xff0c;知道了每个动作都会添加到Op队列里&#xff0c;并由FragmentTransaction进行管理&#xff0c;那么我们就来看看FragmentTransaction的具体内容。 首先FragmentTransacti…

酷开系统 | 追求娱乐不止一种方式,酷开科技带你开启新体验!

在当今社会&#xff0c;娱乐方式多种多样&#xff0c;人们对于娱乐的需求和追求也在日益增长。然而&#xff0c;传统的娱乐方式已经无法满足大家对于多元化、个性化的体验需求。此时&#xff0c;酷开科技以其独特的视角和领先的技术&#xff0c;为消费者们带来了全新的娱乐体验…

【数据结构 —— 二叉树的链式结构实现】

数据结构 —— 二叉树的链式结构实现 1.树的概念及其结构1.1.树概念1.2.树的结构1.3树的相关概念1.4.树的表示1.5. 树在实际中的运用&#xff08;表示文件系统的目录树结构&#xff09; 2.二叉树的概念及其结构2.1二叉树的概念2.2.现实中的二叉树&#xff1a;2.3. 特殊的二叉树…

mysql 命令行导入sql 数据,windows导入,强制导入

线上用了polarDB&#xff0c; 本地导入的时候&#xff0c;通过navicat 的备份导入和执行sql文件的方式导入都失败了 用命令行的方式可以导入sql 当我用windows 的cmd 导入的时候&#xff0c;会报一些命令行的错误。 那其实我检查了这个命令是没有问题的。 mysql -uroot -p hu…