基于Go语言实现插入排序算法及优化
作者:陈明勇 发布时间:2024-05-22 10:18:05
插入排序
插入排序是一种简单的排序算法,以数组为例,我们可以把数组看成是多个数组组成。插入排序的基本思想是往前面已排好序的数组中插入一个元素,组成一个新的数组,此数组依然有序。光看文字可能不理解,让我们看看图示:
插入排序的时间复杂度为 O(N²)。
算法实现
import (
"fmt"
)
func main() {
nums := [4]int{4, 1, 3, 2}
fmt.Println("原数组:", nums)
fmt.Println("--------------------------------")
InsertionSort(nums)
}
func InsertionSort(nums [4]int) {
for i := 1; i < len(nums); i++ {
for j := i; j > 0 && nums[j] < nums[j-1]; j-- {
nums[j], nums[j-1] = nums[j-1], nums[j]
}
fmt.Printf("第 %d 轮后:%v\n", i, nums)
}
fmt.Println("--------------------------------")
fmt.Println("排序后的数组:", nums)
}
执行结果:
原数组: [4 1 3 2]
--------------------------------
第 1 轮后:[1 4 3 2]
第 2 轮后:[1 3 4 2]
第 3 轮后:[1 2 3 4]
--------------------------------
排序后的数组: [1 2 3 4]
1.第一层循环的 i
变量,表示待排序的元素;
2.第二层循环:
j
变量的初值为 i
的值,由 j
变量往前去寻找待插入的位置;
循环条件为
j > 0 && nums[j] < nums[j - 1]
:j > 0
→ 寻找到左边界则结束寻找;
nums[j] < nums[j - 1]
→ 左边元素小于待排序的元素则结束寻找;
3.循环体为元素交换逻辑,只要满足循环条件,则不断交换元素,直到交换到待插入的位置,才终止。
算法优化
上面的代码,是通过不断地交换元素,直到无法交换,才能将元素放置到待插入的位置,为了避免频繁交换元素而导致效率低,将交换的逻辑变成把前面的数往后移,最后再将待排序的元素插入到合适的位置即可。
import (
"fmt"
)
func main() {
nums := [4]int{4, 1, 3, 2}
fmt.Println("原数组:", nums)
fmt.Println("--------------------------------")
InsertionSort(nums)
}
func InsertionSort(nums [4]int) {
for i := 1; i < len(nums); i++ {
t := nums[i]
j := i
for ; j > 0 && t < nums[j-1]; j-- {
nums[j] = nums[j-1]
}
nums[j] = t
fmt.Printf("第 %d 轮后:%v\n", i, nums)
}
fmt.Println("--------------------------------")
fmt.Println("排序后的数组:", nums)
}
用变量 t
记录待排序的元素,用 j
变量往前查找,只要前面的数比 t
大,那么就往后移,最后将 t
插入到合适的位置。
小结
本文首先对插入排序进行简单地介绍,通过图片来演示插入排序的过程,然后使用 Go
语言实现插入排序的算法。为减少算法中交换次数的逻辑,对算法进行优化,将交换的逻辑变成把前面的数往后移,最后将待排序的数插入到合适的位置即可。
除了这种优化方式,还有一种改造方式:普通的算法往左查找的方式是线性查找,由于元素是有序的,因此线性查找可以换成二分查找,但是经过二分找到待插入的位置之后,也得移动前面的元素,相比上面的优化方法,还多了 O(logn) 的查找时间复杂度,因此我认为没有必要改造成二分查找。
来源:https://juejin.cn/post/7175178438095929404


猜你喜欢
- 一、Pandas如何对Categorical类型字段数据统计实战场景:对Categorical类型字段数据统计,Categorical类型是
- 今天在一个QQ群中看到有人在问一个进度条的实现方式,当时因为工作时间,需求相对也比较紧,只是简单的说了一下可以通过CSS的边框属性和背景属性
- 1.Django的简介Django是一个基于MVC构造的框架。但是在Django中,控制器接受用户输入的部分由框架自行处理,所以 Djang
- 背景自从把我手上的任务全部转换成docker运行和管理之后,遇到了一系列的坑,这次是mysql备份的问题。原因是启动mysql镜像的时候没有
- 本文实例讲述了PHP实现无限极分类的两种方式。分享给大家供大家参考,具体如下:面试的时候被问到无限极分类的设计和实现,比较常见的做法是在建表
- 使用django实现注册登录的话,注册登录都有现成的代码,主要是自带的User字段只有(email,username,password),所
- 目录1 请求和响应1.1 请求1.2 响应2 视图2.1 基于APIView写接口2.2 基于GenericAPIView写的接口2.3 基
- 循环导入是指两个文件相互导入对方,形成一个导入循环。这会导致Python无法确定哪个模块应该先导入,进而出现错误。举个Flask中的例子:在
- interfaceGo语言里面设计最精妙的应该算interface,它让面向对象,内容组织实现非常的方便,当你看完这一章,你就会被inter
- 1.首先需要安装pandas, 安装的时候可能由依赖的包需要安装,根据运行时候的提示,缺少哪个库,就pip 安装哪个库。2.示例代码impo
- 本文实例为大家分享了python实现坦克大战游戏的具体代码,供大家参考,具体内容如下游戏界面pygame游戏引擎的安装pip安装window
- Python docx库代码演示安装需要lxml pip install python-docx主业务代码from openpyxl imp
- 如下所示:# -*- coding:utf-8 -*-class Solution: # matrix类型为二维列表,需要返回列
- 许多函数式文章讲述的是组合,流水线和高阶函数这样的抽象函数式技术。本文不同,它展示了人们每天编写的命令式,非函数式代码示例,以及将这些示例转
- 1,CSS,JS,IMG一个都不能少运行代码框<style type="text/css">&l
- 知识点: 1、拼接SQL 2、UNION ALL 3、EXEC 其代码如下: 代码如下:--测试示例 declare @sql
- PHP 向它运行的任何脚本提供了大量的预定义常量。魔术常量准确来说并不能算是常量,常量我们在之前的文章中我们介绍到,常量被定义之后是不能被改
- jsonp方式一:指定返回方法# 后端def view(request): callback = request.GET.get
- python中的print()函数和java中的System.out.print()函数都有着打印字符串的功能。python中:print(
- 本文实例讲述了python实现获取单向链表倒数第k个结点的值。分享给大家供大家参考,具体如下:#初始化链表的结点class Node():