插入排序insertsort

插入排序是一种简单直观的排序算法,适合用于排序小规模数据集。它的基本思想是通过构建一个有序序列,将未排序的数据逐个插入到已排序的序列中。以下是插入排序的基本步骤:

1. 从第一个元素开始,该元素可以认为已经被排序。
2. 取出下一个元素,在已经排序的元素序列中从后向前扫描。
3. 如果该元素(已排序)大于新元素,将该元素移到下一位置。
4. 重复步骤3,直到找到已排序的元素小于或等于新元素的位置。
5. 将新元素插入到该位置后。
6. 重复步骤2~5。

以下是插入排序的一个简单实现(以Python为例):

```python
def insertion_sort(arr):
    for i in range(1, len(arr)):  # 从第一个元素开始,所以从索引1开始
        key = arr[i]  # 记录当前要插入的元素
        j = i - 1
        # 将大于key的元素向后移动
        while j >= 0 and arr[j] > key:
            arr[j + 1] = arr[j]
            j -= 1
        arr[j + 1] = key  # 插入元素
    return arr

# 示例使用
arr = [12, 11, 13, 5, 6]
sorted_arr = insertion_sort(arr)
print("排序后的数组:", sorted_arr)
```

这个算法的时间复杂度为 \(O(n^2)\),其中 \(n\) 是数组的长度。在数组基本有序的情况下,插入排序效率较高。希望这个解释能帮助你理解插入排序的工作原理!

当然,下面是对这段插入排序代码的逐行逐词解释:

```python
def insertion_sort(arr):
```
- `def`: 定义一个函数。
- `insertion_sort`: 函数的名称。
- `arr`: 函数的参数,表示要排序的数组。

```python
    for i in range(1, len(arr)):  # 从第一个元素开始,所以从索引1开始
```
- `for`: 开始一个循环。
- `i`: 循环变量,表示当前要处理的元素的索引。
- `in`: 用于指定循环的范围。
- `range(1, len(arr))`: 生成从1到数组长度减1的数字序列。我们从索引1开始,因为索引0的元素可以认为是已经被排序的。
- `len(arr)`: 获取数组的长度。

```python
        key = arr[i]  # 记录当前要插入的元素
```
- `key`: 临时变量,用于存储当前要插入到已排序部分的元素。
- `arr[i]`: 获取数组中索引为`i`的元素。

```python
        j = i - 1
```
- `j`: 初始化为`i`的前一个索引,用于遍历已排序部分。
- `i - 1`: 计算当前索引的前一个位置。

```python
        while j >= 0 and arr[j] > key:
```
- `while`: 开始一个循环,只要条件为真就继续执行。
- `j >= 0`: 确保索引`j`在数组范围内。
- `and`: 逻辑与操作符。
- `arr[j] > key`: 检查已排序部分的当前元素是否大于`key`。

```python
            arr[j + 1] = arr[j]
```
- `arr[j + 1]`: 将当前元素的下一个位置设置为当前元素。
- `=`: 赋值操作。
- `arr[j]`: 获取当前已排序部分的元素。

```python
            j -= 1
```
- `j -= 1`: 将`j`的值减1,用于向前移动到下一个元素。

```python
        arr[j + 1] = key  # 插入元素
```
- `arr[j + 1]`: 将`key`插入到正确的位置。
- `=`: 赋值操作。
- `key`: 放置在正确位置的当前元素。

```python
    return arr
```
- `return`: 返回排序后的数组。
- `arr`: 已排序的数组。

```python
# 示例使用
arr = [12, 11, 13, 5, 6]
```
- `arr = [12, 11, 13, 5, 6]`: 定义一个要排序的数组。

```python
sorted_arr = insertion_sort(arr)
```
- `sorted_arr`: 存储排序后的数组。
- `insertion_sort(arr)`: 调用`insertion_sort`函数,对`arr`进行排序。

```python
print("排序后的数组:", sorted_arr)
```
- `print`: 输出函数。
- `"排序后的数组:"`: 输出的提示信息。
- `sorted_arr`: 打印排序后的数组。 

这段代码实现了插入排序算法,用于对数组`arr`进行排序并输出结果。

好的,让我们一步步地跟踪插入排序算法如何对数组 `[12, 11, 13, 5, 6]` 进行排序。

### 初始状态
- 数组:`[12, 11, 13, 5, 6]`

### 第一次迭代 (`i = 1`)
- `key = arr[1] = 11`
- `j = 0`
- 比较 `arr[j] (12)` 和 `key (11)`:
  - 因为 `12 > 11`,所以将 `arr[j + 1] = arr[j]`,数组变为 `[12, 12, 13, 5, 6]`
  - `j -= 1`,所以 `j = -1`
- 插入 `key` 到 `arr[j + 1]`,即 `arr[0] = 11`,数组变为 `[11, 12, 13, 5, 6]`

### 第二次迭代 (`i = 2`)
- `key = arr[2] = 13`
- `j = 1`
- 比较 `arr[j] (12)` 和 `key (13)`:
  - 因为 `12 <= 13`,不需要移动元素
- 插入 `key` 到 `arr[j + 1]`,即 `arr[2] = 13`(保持不变),数组仍为 `[11, 12, 13, 5, 6]`

### 第三次迭代 (`i = 3`)
- `key = arr[3] = 5`
- `j = 2`
- 比较 `arr[j] (13)` 和 `key (5)`:
  - 因为 `13 > 5`,将 `arr[j + 1] = arr[j]`,数组变为 `[11, 12, 13, 13, 6]`
  - `j -= 1`,所以 `j = 1`
- 比较 `arr[j] (12)` 和 `key (5)`:
  - 因为 `12 > 5`,将 `arr[j + 1] = arr[j]`,数组变为 `[11, 12, 12, 13, 6]`
  - `j -= 1`,所以 `j = 0`
- 比较 `arr[j] (11)` 和 `key (5)`:
  - 因为 `11 > 5`,将 `arr[j + 1] = arr[j]`,数组变为 `[11, 11, 12, 13, 6]`
  - `j -= 1`,所以 `j = -1`
- 插入 `key` 到 `arr[j + 1]`,即 `arr[0] = 5`,数组变为 `[5, 11, 12, 13, 6]`

### 第四次迭代 (`i = 4`)
- `key = arr[4] = 6`
- `j = 3`
- 比较 `arr[j] (13)` 和 `key (6)`:
  - 因为 `13 > 6`,将 `arr[j + 1] = arr[j]`,数组变为 `[5, 11, 12, 13, 13]`
  - `j -= 1`,所以 `j = 2`
- 比较 `arr[j] (12)` 和 `key (6)`:
  - 因为 `12 > 6`,将 `arr[j + 1] = arr[j]`,数组变为 `[5, 11, 12, 12, 13]`
  - `j -= 1`,所以 `j = 1`
- 比较 `arr[j] (11)` 和 `key (6)`:
  - 因为 `11 > 6`,将 `arr[j + 1] = arr[j]`,数组变为 `[5, 11, 11, 12, 13]`
  - `j -= 1`,所以 `j = 0`
- 比较 `arr[j] (5)` 和 `key (6)`:
  - 因为 `5 <= 6`,不需要移动元素
- 插入 `key` 到 `arr[j + 1]`,即 `arr[1] = 6`,数组变为 `[5, 6, 11, 12, 13]`

### 最终结果
- 排序完成后的数组是 `[5, 6, 11, 12, 13]`

这个过程展示了插入排序如何通过逐步构建一个有序的数组部分来完成排序。

插入排序的时间复杂度分析主要包括两个方面:**最佳情况** 和 **最坏情况**。我们来一步步分析这两种情况。

### 最佳情况
在最佳情况下,数组已经是有序的。对于一个长度为 \( n \) 的数组:

1. 外层循环运行 \( n-1 \) 次(从索引 1 到 \( n-1 \))。
2. 内层 `while` 循环的条件 `arr[j] > key` 总是为假,因为数组已经有序。
3. 因此,内层 `while` 循环不会执行移动操作。

**时间复杂度**:
- 外层循环:运行 \( n-1 \) 次。
- 内层循环:0 次(因为数组有序)。

总的来说,最佳情况下的时间复杂度是 \( O(n) \)。

### 最坏情况
在最坏情况下,数组是按降序排列的。对于一个长度为 \( n \) 的数组:

1. 外层循环运行 \( n-1 \) 次。
2. 内层 `while` 循环在每次迭代中都要比较并移动元素,直到找到合适的位置插入当前元素。
3. 第 \( i \) 次外层循环中,内层 `while` 循环最多需要比较 `i` 次,因为当前元素需要插入到已排序部分的最前面。

**时间复杂度**:
- 外层循环:运行 \( n-1 \) 次。
- 内层循环:对于第 \( i \) 次外层循环,内层循环运行 \( i \) 次。

计算总的比较和移动操作数:
- \[
  \sum_{i=1}^{n-1} i = 1 + 2 + 3 + \ldots + (n-1) = \frac{(n-1) \times n}{2}
  \]

因此,最坏情况下的时间复杂度为 \( O(n^2) \)。

### 平均情况
在平均情况下,数组元素是随机排列的。对每个元素,平均来说需要移动大约一半的已排序部分元素。虽然求具体的平均复杂度有些复杂,但通常认为:

- 平均情况下时间复杂度是 \( O(n^2) \),因为内层循环的平均执行次数在逐渐增加。

### 空间复杂度
- 插入排序是就地排序算法,因此空间复杂度是 \( O(1) \),只需要常数级别的额外存储空间。 

总结来说,插入排序的时间复杂度在最佳情况下为 \( O(n) \),而在最坏和平均情况下为 \( O(n^2) \)。

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

vTESTstudio系列15--vTESTstudio-Doors的需求和测试用例的管理

最近有朋友在咨询vTESTstudio中怎么去跟Doors里面的需求去做好管理这方面的问题&#xff0c;临时加两篇文章介绍一下,Lets Go!!! 目录 1.Doors的配置&#xff1a; 1.1 安装Doors AddIn for vTESTstudio&#xff1a; 1.2 更新XML脚本&#xff1a; 1.3 导出需求的Trace Item…

基于Java Springboot编程语言在线学习平台

一、作品包含 源码数据库设计文档万字PPT全套环境和工具资源部署教程 二、项目技术 前端技术&#xff1a;Html、Css、Js、Vue、Element-ui 数据库&#xff1a;MySQL 后端技术&#xff1a;Java、Spring Boot、MyBatis 三、运行环境 开发工具&#xff1a;IDEA/eclipse 数据…

JDK安装报错“以下应用程序正在使用需要由此安装程序更新的文件”

&#xff08;一&#xff09;问题描述 我刚刚没有截图&#xff0c;这是我在网上看到的图&#xff1a; &#xff08;二&#xff09;可能的解决办法 1. 下方工具栏右键&#xff0c;打开任务管理器按钮&#xff0c;在进程中找到“Java Platform SE binary” 进程&#xff0c;右键结…

数据库第3次作业

学生表&#xff1a;Student (Sno, Sname, Ssex , Sage, Sdept) 学号&#xff0c;姓名&#xff0c;性别&#xff0c;年龄&#xff0c;所在系 Sno为主键 课程表&#xff1a;Course (Cno, Cname,) 课程号&#xff0c;课程名 Cno为主键 学生选课表&#xff1a;SC (Sno, Cno, Score)…

Linux之文件系统,软硬连接和动静态库

Linux之文件系统&#xff0c;软硬连接和动静态库 一.文件系统1.1磁盘的存储结构1.2CHS和LBA1.3ext2文件系统 二.软硬连接2.1软链接2.2硬链接 三.静态库和动态库3.1静态库与动态库的概念3.2静态库的创建与使用3.3动态库的创建与使用3.4动态库的加载 一.文件系统 在上篇的学习中…

【项目开发】URL中井号(#)的技术细节

未经许可,不得转载。 文章目录 前言一、# 的基本含义二、# 不参与 HTTP 请求三、# 后的字符处理机制四、# 的变化不会触发网页重新加载五、# 的变化会记录在浏览器历史中六、通过 window.location.hash 操作七、onhashchange 事件八、Google 对 # 的处理机制前言 2023 年 9 月…

TikZ 绘图学习笔记

这篇笔记的所有代码如下&#xff1a; % !TEX TS-program pdflatex % !TEX encoding UTF-8 Unicode% This is a simple template for a LaTeX document using the "article" class. % See "book", "report", "letter" for other typ…

Android Framework层介绍

文章目录 前言一、Android Framework 层概述二、主要组件1. 应用程序接口&#xff08;API&#xff09;2. 系统服务3. Binder4. 资源管理5. Content Provider6. 广播接收器&#xff08;BroadcastReceiver&#xff09;7. 服务&#xff08;Service&#xff09; 三、与 Linux Kerne…

如何选择等保服务

在当今信息化高速发展的时代&#xff0c;企业信息系统已成为业务运营的核心支撑&#xff0c;其安全性直接关系到企业的生存与发展。为了应对日益复杂的网络安全威胁&#xff0c;国家推行了等级保护&#xff08;简称等保&#xff09;制度&#xff0c;作为一项基本的信息安全保障…

MCU中的定时器

第一章 定时器的应用场景 第二章 定时器的原理 2.1 定时器的计数原理 1. 定时器的本质是一个计数器&#xff1b; 2. 计数器是对输入的系统频率信号进行计数&#xff1b; 3. 每来一个周期的信号&#xff0c;计数器的cnt 加一。如果周期T表示为1s&#xff0c;来三个周期就表示…

主页任务与计算器任务

一、主页任务 /* Private includes -----------------------------------------------------------*/ //includes #include "user_TasksInit.h" #include "user_ScrRenewTask.h" #include "main.h" #include "rtc.h" #include "…

javascript 入门-01-变量声明

因缘际会 Alice: 编程入门好像很难吧,我能学会吗 ?我虽然是计算机专业的,但是我几乎没怎么写过代码。但是你先别说我菜,我身边的同学大家都是这样的 🤷 Bob: 那你能写冒泡排序或者求数组最大值吗 ? Alice: 冒泡排序写不出来,求数组最大值还能试试看。不过为什么问这个…

富士施乐DocuContre S2520报打开盖子A,取出纸张。代码077-900故障检修

故障描述: 一台富士施乐DocuContre S2520复印机开机报错:打开盖子A,取出纸张。代码077-900故障,用户之前经常卡纸,卡着、卡着就一直提示打开盖子A,取出纸张了;复印机屏幕提示如下图: 故障检修: 富士施乐DocuContre S2520复印机报打开盖子A,取出纸张。077-900的错误代…

MySQL事务相关面试题

MySQL事务 事务的特性是什么&#xff1f; 事务是一组操作的集合&#xff0c;是不可分割的单位&#xff0c;把所有操作作为一个整体要么同时成功&#xff0c;要么同时失败 ACID 并发事务问题 脏读&#xff1a;一个事务读到了另外一个事务还没有提交的数据 不可重复读&#x…

深度学习与飞桨 PaddlePaddle Fluid

编辑推荐 飞桨PaddlePaddle是百度推出的深度学习框架&#xff0c;不仅支撑了百度公司的很多业务和应用&#xff0c;而且随着其开源过程的推进&#xff0c;在其他行业得到普及和应用。 本书基于2019年7月4日发布的飞桨PaddlePaddle Fluid 1.5版本&#xff08;后续版本会兼容旧版…

C++ | Leetcode C++题解之第564题寻找最近的回文数

题目&#xff1a; 题解&#xff1a; using ULL unsigned long long;class Solution { public:vector<ULL> getCandidates(const string& n) {int len n.length();vector<ULL> candidates {(ULL)pow(10, len - 1) - 1,(ULL)pow(10, len) 1,};ULL selfPrefi…

解决IDEA报包不存在,但实际存在的问题

前言 最近在把一个亿老项目交割给同事&#xff0c;同事在导入项目运行时遇到IDEA报包不存在&#xff0c;但实际存在的问题&#xff0c;最终通过以下方式解决 现象 在IDEA里启动运行项目&#xff0c;报某个类有问题&#xff0c;引入的包不存在。 点击这个引入的包&#xff0c;可…

Jenkins下载安装、构建部署到linux远程启动运行

Jenkins详细教程 Winodws下载安装Jenkins一、Jenkins配置Plugins插件管理1、汉化插件2、Maven插件3、重启Jenkins&#xff1a;Restart Safely插件4、文件传输&#xff1a;Publish Over SSH5、gitee插件6、清理插件&#xff1a;workspace cleanup system系统配置1、Gitee配置2、…

三、计算机视觉_04AlexNet、VggNet、ResNet设计思想

1、AlexNet 1.1 基本介绍 AlexNet是由Alex Krizhevsky、Ilya Sutskever和Geoffrey Hinton在2012年ImageNet大规模视觉识别挑战赛&#xff08;ILSVRC&#xff09;中提出的&#xff0c;它不仅赢得了当届的比赛&#xff0c;还激发了后续许多创新的神经网络架构&#xff08;如VGGN…

基于SpringBoot的在线考试系统的设计与实现+文档

&#x1f497;博主介绍&#x1f497;&#xff1a;✌在职Java研发工程师、专注于程序设计、源码分享、技术交流、专注于Java技术领域和毕业设计✌ 温馨提示&#xff1a;文末有 CSDN 平台官方提供的老师 Wechat / QQ 名片 :) Java精品实战案例《700套》 2025最新毕业设计选题推荐…