[Golang]数组删除的一些小坑

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动

在golang中自带的slice不存在remove的操作,对于可能存在的数组删除操作,就需要其他方法:

一、slice的append函数

这一个方法是比较常见的方法,使用append拼接除被删除元素外的上下两部分函数。

具体实现也较为简单:

s := []int{0, 1, 2, 3, 4}
index := 2    // 想要删除的元素下标
s = append(s[:index], s[index:]...)
// s => [0, 1, 3, 4]
复制代码

主要要注意的是...(解构方法)的使用,这实际上是golang的一个语法糖,在slice作为参数时将slice拆散传入,相当于进行了一个for遍历,将slice内的所有元素依次投递出来。至于为什么要这样做,是因为append的第二个参数,即待加入的元素,需要接受可变函数,直接传入slice是不能被识别的,需要将数组解构成多个参数传入,才能被识别。

至于如何定位到所要删除的元素下表,则可以使用sort包的sort.search()使用二分查找进行搜索(复杂度O(logn))。

二、使用container/list包

由于数组删除需要移动元素,复杂度较高O(n),因此在频繁出现删除操作的情景,就可以使用链表进行替代:

在container/list中,list类提供了一个Remove函数,可以想在python里面一样使用remove通过传入元素的方式进行删除。

使用方法也比较简单:

l.Remove(a)
复制代码

链表中的删除无需移动元素,只需要将删除元素前后两头尾指针项目连接即可,复杂度极低O(1)。

但是其缺点也较为明显,在查询中,只能使用遍历的方式定位元素,时间复杂度O(n)。

因此,链表一般用于头尾元素修改频繁的情景。