Go 实现插入排序算法及优化

插入排序

插入排序是一种简单的排序算法,以数组为例,我们可以把数组看成是多个数组组成。插入排序的基本思想是往前面已排好序的数组中插入一个元素,组成一个新的数组,此数组依然有序。光看文字可能不理解,让我们看看图示:

插入排序的时间复杂度为 O(N²)。

算法实现

go 复制代码
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)
}

执行结果:

go 复制代码
原数组: [4 1 3 2]
--------------------------------
第 1 轮后:[1 4 3 2]
第 2 轮后:[1 3 4 2]
第 3 轮后:[1 2 3 4]
--------------------------------
排序后的数组: [1 2 3 4]

原数组: [4 1 3 2]

第 1 轮后:[1 4 3 2]

第 2 轮后:[1 3 4 2]
第 3 轮后:[1 2 3 4]

排序后的数组: [1 2 3 4]

算法优化

上面的代码,是通过不断地交换元素,直到无法交换,才能将元素放置到待插入的位置,为了避免频繁交换元素而导致效率低,将交换的逻辑变成把前面的数往后移,最后再将待排序的元素插入到合适的位置即可。

go 复制代码
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) 的查找时间复杂度,因此我认为没有必要改造成二分查找。

相关推荐
数据皮皮侠AI2 天前
中国城市可再生能源数据集(2005-2021)|顶刊 Sci Data 11 种能源面板
大数据·人工智能·笔记·能源·1024程序员节
计算机毕业论文辅导4 天前
物联网实战:基于MQTT协议的智能家居数据传输系统设计与实现
1024程序员节
开开心心就好5 天前
支持批量处理的视频分割工具推荐
安全·智能手机·rust·pdf·电脑·1024程序员节·lavarel
liuyao_xianhui7 天前
Linux开发工具结尾 _make
linux·运维·服务器·数据结构·哈希算法·宽度优先·1024程序员节
学传打活9 天前
【边打字.边学昆仑正义文化】_21_爱的结晶(1)
微信公众平台·1024程序员节·汉字·昆仑正义文化
数据皮皮侠AI16 天前
顶刊同款!中国地级市风灾风险与损失数据集(2000-2022)|灾害 / 环境 / 经济研究必备
大数据·人工智能·笔记·能源·1024程序员节
Fab1an17 天前
Busqueda——Hack The Box 靶机
linux·服务器·学习·1024程序员节
技术专家17 天前
Stable Diffusion系列的详细讨论 / Detailed Discussion of the Stable Diffusion Series
人工智能·python·算法·推荐算法·1024程序员节
学传打活20 天前
古代汉语是源,现代汉语是流,源与流一脉相承。
微信公众平台·1024程序员节·汉字·中华文化
学传打活25 天前
【边打字.边学昆仑正义文化】_19_星际生命的生存状况(1)
微信公众平台·1024程序员节·汉字·昆仑正义文化