Go版数据结构 -【8.3 插入排序】

news2024/10/10 18:28:10

8.3 插入排序

插入排序是一种简单且直观的排序算法,它的基本思想是将数组分为已排序和未排序两个部分。

通过逐步将未排序部分的元素插入到已排序部分的正确位置,逐步构建整个有序序列。

看起来与选择排序是差不多的,但是还是有一些差别的。

选择排序是一直从未排序序列中选择最小/最大的元素插入到已排序队列中。

而插入排序则是:每次从未排序的序列中拿到第一个元素,与已排序序列的元素比较,之后找到它自己合适的位置插入进去。

本节代码存放目录为 lesson19


概念与原理

插入排序的原理如下:

  • 将第一个元素视为已排序部分,其他元素为未排序部分。

  • 从未排序部分的第一个元素开始,将其与已排序部分的元素逐个比较,找到其正确位置并插入。

  • 重复步骤 2,直到所有元素都插入到已排序部分。

插入排序的基本特点:

  • 时间复杂度为 O(n^2),适合少量数据的排序。

  • 插入排序是稳定的,因为相同元素的相对顺序不会改变。


插入排序的步骤示例

给定如下无序数组,按照从小到大排序:

[5, 3, 8, 4, 2]

通过插入排序的步骤如下:

第一轮:

- 第一个元素 5 作为已排序部分,即:[5]

- 将 3 插入到已排序部分 [5],结果:[3, 5, 8, 4, 2]

第二轮:

- 将 8 插入到已排序部分 [3, 5],结果:[3, 5, 8, 4, 2]

第三轮:

- 将 4 插入到已排序部分 [3, 5, 8],结果:[3, 4, 5, 8, 2]

第四轮:

- 将 2 插入到已排序部分 [3, 4, 5, 8],结果:[2, 3, 4, 5, 8]

最终,排序结果为 [2, 3, 4, 5, 8]


插入排序的时间复杂度

插入排序的时间复杂度取决于数组的初始状态:

  • 最坏情况O(n²),即数组是反序排列的。

  • 最好情况O(n),即数组已经是有序的。

  • 平均情况O(n²),即数组是随机排列的。

Go语言的实现

实现代码如下:

func insertionSort(arr []int) {
	// 从第二个元素开始遍历,认为第一个元素是已排序的
	for i := 1; i < len(arr); i++ {
		key := arr[i]
		j := i - 1

		// 在已排序部分中寻找插入位置
		for j >= 0 && arr[j] > key {
			arr[j+1] = arr[j] // 将比key大的元素右移
			j--
		}
		arr[j+1] = key // 插入key到正确位置

		fmt.Printf("第 %d 轮插入结果: %v\n", i, arr)
	}
}

func main() {
	arr := []int{5, 3, 8, 4, 2}
	insertionSort(arr)
	fmt.Println("最终排序结果: ", arr)
}

执行结果如下所示:

1 轮插入结果: [3 5 8 4 2]2 轮插入结果: [3 5 8 4 2]3 轮插入结果: [3 4 5 8 2]4 轮插入结果: [2 3 4 5 8]
最终排序结果:  [2 3 4 5 8]

通过上面的实现,我们可以看到插入排序通过一轮一轮地将元素插入到正确的位置,逐渐将整个数组变得有序。


小结

本节我们讲解了插入排序的基本原理、步骤示例和 Go 语言的实现。

关于本节总结如下:

  • 时间复杂度:插入排序的时间复杂度为 O(n²),最坏情况下会逐步遍历所有元素。

  • 稳定性:插入排序是稳定的排序算法。

  • 应用场景:插入排序适用于数据量较小或部分已排序的场景,且在数组接近有序时效率较高。


我的GitHub:https://github.com/swxctx

书籍地址:https://gs.golang.website/

书籍代码:https://github.com/YouCanGolang/GoStructedCode

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

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

相关文章

vue cli配置环境变量并使用

1.在根路径下创建.env文件 2.写.env文件内容 文件里存储的值的key要以 VUE_APP 开头 VUE_APP VUE_APP_PUBLIC_PATH/ VUE_APP_PUBLIC_PATH/helper/ 3.使用 publicPath: process.env.VUE_APP_PUBLIC_PATH, 4.配置package.json "serve:production": "vue-cli-s…

FreeRTOS-软件定时器

FreeRTOS-软件定时器 一、软件定时器简介1.1 软件定时器的状态和工作模式 二、软件定时器结构体成员和API函数三、软件定时器实验 一、软件定时器简介 定时器&#xff1a;指定时间开始&#xff0c;经过一个指定的时间&#xff0c;触发一个超时事件&#xff0c;用户可自定义定时…

ThinkPHP5bootstrapMySQL开发学习平台(包括后台管理功能、PC端网页、移动端网页)手把手运行源码

一、项目预览(全部源码链接在最下面) 功能及页面持续优化中...... 二、本地运行方式 1、下载源码包进行解压(源码在最下面) 2、下载phpstudy_pro,并运行Apache&

精华帖分享 | 判定策略失效的新方法——统计假设检验

本文来源于量化小论坛策略分享会板块精华帖&#xff0c;作者为元亨利贞&#xff0c;发布于2023年12月25日。 以下为精华帖正文&#xff1a; 1、起因 去年刚入门B圈&#xff0c;由于之前有做商品期货择时的经验&#xff0c;通常来讲&#xff0c;趋势跟随&#xff0c;并且回测结…

谁说电商选品找货源没有捷径,只要你用对工具!

最近跟很多同行聊&#xff0c;都在抱怨选品难的问题&#xff0c;都说7分靠选品&#xff0c;3分靠运营&#xff0c;对于选品来说&#xff0c;并没有捷径可走&#xff0c;但其实是有很多不同的角度的。 现在市面上大部分开发做的选品&#xff0c;“选品方法”或“产品分析方法”…

SiLM266x系列SiLM2661高压电池组前端充/放电高边NFET驱动器 为电池系统保护提供可靠性和设计灵活性

SiLM2661产品概述&#xff1a; SiLM2661能够灵活的应对不同应用场景对锂电池进行监控和保护的需求&#xff0c;为电池系统保护提供可靠性和设计灵活性。是用于电池充电/放电系统控制的低功耗、高边 N 沟道 FET 驱动器&#xff0c;高边保护功能可避免系统的接地引脚断开连接&am…

Pycharm连接AutoDL服务器 文件上传 启动终端

Pycharm AutoDL 需要使用pycharm专业版&#xff08;学生可以通过教育邮箱认证&#xff0c;每年一次&#xff09;。 首先进入AutoDL官网&#xff1a;AutoDL-品质GPU租用平台-租GPU就上AutoDL进行学生注册登录&#xff08;可以领10元的代金券&#xff09;点击右上角的控制台&am…

京东web 京东e卡绑定 第二部分分析

声明 本文章中所有内容仅供学习交流使用&#xff0c;不用于其他任何目的&#xff0c;抓包内容、敏感网址、数据接口等均已做脱敏处理&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则由此产生的一切后果均与作者无关&#xff01; 有相关问题请第一时间头像私信联系我删…

api测试和接口测试的区别

API测试和接口测试是软件测试中一个非常重要的领域&#xff0c;尤其是在当前Web应用程序和移动应用程序的发展中。虽然它们都测试了Web服务的功能&#xff0c;但是二者在测试方法和测试实施方面存在很大的差异。本文将介绍API测试和接口测试之间的主要区别 API测试的主要关注点…

【WebGis开发 - Cesium】三维可视化项目教程---图层管理基础

目录 引言一、功能设计1. 主体功能2. 细节问题 二、代码实现1. 树形控件2. 全局状态准备3. 创建图层控制方法3.1 加载、卸载方法编写3.2 统一对外暴露入口3.3 提供图层类别的可拓展性3.1 完整代码 4. 效果展示5. hooks函数使用方法 三、总结 引言 本教程主要是围绕Cesium这一开…

华为云服务器公网ip访问不通解决

问题&#xff1a;用弹性公网IP登录超时&#xff0c;ping不通&#xff0c;但是VNC方式可以登陆成功 解决&#xff1a;执行ifconfig&#xff0c;看到eth0网卡没有获取到 ifconfig 执行dhclient自动获取下网卡 &#xff1a; dhclient 再次执行ifconfig&#xff1a;网卡已经获…

【AI论文精读3】RAG论文综述1-P1

AI知识点总结&#xff1a;【AI知识点】 AI论文精读、项目、思考&#xff1a;【AI修炼之路】 简介 论文中英文名 Retrieval-Augmented Generation for Large Language Models: A Survey 面向大型语言模型的检索增强生成&#xff1a;综述 论文地址 arxiv地址&#xff1a;http…

知识蒸馏介绍

一、知识蒸馏介绍 1.1 概念介绍 知识蒸馏&#xff08;knowledge distillation&#xff09;是模型压缩的一种常用的方法&#xff0c;不同于模型压缩中的剪枝和量化&#xff0c;知识蒸馏是通过构建一个轻量化的小模型&#xff0c;利用性能更好的大模型的监督信息&#xff0c;来…

项目经理是怎么慢慢废掉的?这些无意识行为可能会毁了你!

工作久了&#xff0c;每个人都或多或少会有一些无力感和疲惫感。如果没有调整过来&#xff0c;久而久之&#xff0c;会感觉自己好像废掉了&#xff0c;做什么事情都打不起精神。 如果你是项目经理&#xff0c;工作中有这样一些迹象&#xff0c;比如总是拖延时间、丧失自己的判…

【进程间通信(三)】【system V共享内存】

目录 1. 原理2. 编码通信2.1 创建共享内存2.2 shmat && shmdt && shmctl2.3 通信 3. 共享内存的特性3.1 共享内存的属性3.2 加入管道实现同步机制 前面的文章介绍了管道通信&#xff0c;其中包括匿名管道、命名管道。这篇文章介绍另一种进程间通信的方式 -----…

NVP的含义?如何理解其在AEM|FLUKE线缆认证测试中的意义?不同的NVP会出现怎样的结果?

在AEM|FLUKE铜缆认证测试中&#xff0c;有很多朋友对NVP设置有疑问&#xff0c;不知道应该怎么去设置它&#xff0c;并很好的应用它&#xff0c;那我们基于此&#xff0c;做一个简单的分析。 什么是NVP? NVP是Nominal Velocity of Propagation的缩写&#xff1f;简单直接译过…

Java基础-泛型机制

文章目录 为什么引入泛型泛型的基本使用泛型类泛型接口泛型方法泛型数组正确的数组声明使用场景如何理解Java中的泛型是伪泛型&#xff1f;泛型中类型擦除 泛型数组&#xff1a;如何正确的初始化泛型数组实例&#xff1f; 为什么引入泛型 引入泛型的意义在于&#xff1a; 适用…

KEYSIGHT B1500A 半导体器件参数分析仪

新利通 B1500A 半导体器件参数分析仪 ——一体化器件表征分析仪—— 简述 Keysight B1500A 半导体参数分析仪是一款一体化器件表征分析仪&#xff0c;能够测量 IV、CV、脉冲/动态 IV 等参数。 主机和插入式模块能够表征大多数电子器件、材料、半导体和有源/无源元器件。 B…

关于相机的一些零碎知识点

热成像&#xff0c;英文为Thermal Imaging&#xff0c;例如型号500T&#xff0c;其实指的就是热成像500分辨率。 相机的CMOS&#xff0c;英文为Complementary Metal Oxide Semiconductor&#xff0c;是数码相机的核心成像部件&#xff0c;是一种互补金属氧化物导体器件。 DPI…