1.机缘
在与学长的交流中,了解到在Go中链表的增删还有利用append的增删,因为之前有对切片进行删改操作,所以觉得在Go中,可能不需要链表,就可以完成操作所以进行了两者的时间复杂度的比较。
1.append的介绍
在go语言中,append()函数用于为切片动态添加元素,可以将元素添加到切片末尾并返回结果;调用append函数必须用原来的切片变量接收返回值,追加一个元素可使用“slice = append(slice,elem1,elem2)”语句,追加一个切片可使用“slice = append(slice,anotherSlice...)”语句。
- append()用来将元素添加到切片末尾并返回结果。
- 调用append函数必须用原来的切片变量接收返回值
- append追加元素,如果slice还有容量的话,就会将新的元素放在原来slice后面的剩余空间里,当底层数组装不下的时候,Go就会创建新的底层数组来保存这个切片,slice地址也随之改变。
- 分配了新的地址后,再把原来slice中的元素逐个拷贝到新的slice中,并返回。
append不仅可以添加元素,也可以添加切片。
2.计算两者运行时间大小的时间函数
now := time.Now()//计算出当前的时间
Time = time.Now().UnixMilli() - now.UnixMilli()//用当前的时间减去之间记录的时间
我们可以利用time函数进行计时,这里我们用的纳秒,还可以用毫秒,多种时间计算方法。
2.操作
1.链表的操作
我们编写了链表的增删,因为切片只能进行扩展,不能在特定位置进行删除,我们主要用链表的删除操作来计时,看看两者的特定位置插入的和直接插入的两者时间。
package operator
import (
"fmt"
"time"
)
type node struct {
id int
next *node
}
type list struct {
head *node
}
func NewList() *list {
l := &list{}
l.head = &node{}
l.head.next = nil
return l
}
func (l *list) Insert(k int, id int) {
//if l.head.next == nil {
// p := new(node)
// p.id = id
// p.next = nil
// l.head.next = p
// //fmt.Println(l.head.next.id)
// return
//}
i := 0
t := l.head
temp := l.head.next
for i = 1; i < k && temp != nil; i++ {
//fmt.Println("adsd")
temp = temp.next
t = t.next
}
//fmt.Println(i, k)
if i == k {
p := new(node)
p.id = id
p.next = nil
t.next = p
p.next = temp
//fmt.Println(p.id)
//temp.next = p
} else {
fmt.Println("没有找到")
return
}
return
}
func (l *list) delete(k int) {
t := l.head
temp := l.head.next
i := 0
for i = 1; i < k; i++ {
if temp.next == nil {
break
}
temp = temp.next
t = t.next
}
if i == k {
if temp.next == nil {
t.next = nil
} else {
t.next = temp.next
}
} else {
fmt.Println("没有找到")
return
}
return
}
func (l *list) printf() {
fmt.Println("打印数据为")
for temp := l.head.next; temp != nil; temp = temp.next {
fmt.Print(temp.id, " ")
}
}
func Analyse01() {
l := NewList()
l.Insert(1, 8)
l.Insert(2, 5)
l.Insert(3, 0)
for i := 0; i < 90000; i++ {
l.Insert(2, i)
}
//l.Insert(5, 1)
//l.Insert(2, 2)
//l.Insert(2, 9)
//l.printf()
//l.delete(6)
//l.delete(5)
//l.printf()
now := time.Now()
for i := 0; i < 90000; i++ {
l.delete(2)
}
fmt.Println(time.Now().UnixMilli() - now.UnixMilli())
}
2.append对切片进行删除
这里是我们进行对切片特定地方删除的操作,我们也可以使用这个进行扩展操作,统计时间。
package operator
import (
"fmt"
"time"
)
func Analyse02() {
var a []int
a = append(a, 1)
a = append(a, 2)
for i := 0; i < 90000; i++ {
a = append(a, i)
}
s := time.Now()
for i := 0; i < 90000; i++ {
a = append(a[0:1], a[2:]...)
}
fmt.Println(time.Now().UnixMilli() - s.UnixMilli())
}
3.特定位置删除的时间

从图中我们可以看出,相同的数据下,两者的时间差距是很大的
4.直接进行插入

我们数据增加到90000000时再进行增加,就会发现链表的时间远远大于append

但是当我们把数据减少到90000时就会发现两者的差距很小了,
3.总结
我们可以看出来两者的比较,所以就明白了,append进行删除的时候,其实是对这个切片重新进行了空间分配,所以这样大大增加了时间,但是再扩展的时候只是进行增加,扩容的时候并且还是以二倍的速度进行扩容,所以这个时间就是大大减少了,所以我们在合理的时候需要用到合理的方法,这样才可以是我们编写的程序的时间大大减少。
797

被折叠的 条评论
为什么被折叠?



