Go从入门到精通——列表(list)——可以快速增删的非连续空间的容器

列表(list)——可以快速增删的非连续空间的容器

1.1、列表原理

  列表是一种非连续存储的容器,由多个节点组成,节点通过一些变量记录彼此之间的关系。列表有多种实现方法,如单链表、双链表等。

  列表的原理可以这样理解:假设 A、B、C 三个人都有电话号码,如果 A 把号码告诉给 B,B 把号码告诉给 C,这个过程就建立了一个

单链表结构:

双链表结构:

  如果需要获得所有人的号码,只需要从 A 或者 C 开始,要求他们将自己的号码发出来,然后再通知下一个人如此循环。这个过程就是列表遍历

  如果 B 换号码了,他需要通知 A 和 C,将自己的号码移除。这个过程就是列表元素的删除操作

  在 Go 语言中,将列表使用 container/list 包来实现,内部的实现原理是双链表。列表能高效地进行任意位置的元素插入和删除操作。

1.2、初始化列表

  list 的初始化有两种方法,两种方法的初始化效果是一致的:

    • new
    • 声明

  1.2.1、通过 container/list 包的 New 方法初始化 list

1
变量名 := list.New()

  1.2.2、通过声明初始化 list

var 变量名 list.List

  列表与切片和 map 不同的是,列表并没有具体元素类型的限制。因此,列表的元素可以是任意类型。这既带来遍历,也会引来一些问题。给一个列表放入了非期望类型的值,在取出值后,将 interface{} 转换为期望类型时将发生宕机。

1.3、在列表中插入元素

  双链表支持从队前方或后方插入元素,分别对应的方法是 PushFront 和 PushBack。

这两个方法都会返回一个 *list.Element 结构。
如果在以后的使用中需要删除插入的元素,则只能通过 *list.Element 配合 Remove() 方法进行删除,这种方法可以让删除更加效率化,也是双链表特性之一

  下面代码展示如何给 list 添加元素:

1
2
3
l := list.New()
l.PushBack("first")
l.PushFront(67)

  代码说明如下:

  • 第 1 行,创建一个列表实例。
  • 第 2 行,将 first 字符串插入到列表的尾部,此时列表是空的,插入后只有一个元素。
  • 第 3 行,将数值 67 放入列表。此时,列表中已经存在 first 元素,67 这个元素将被放在 first 的前面。

列表插入元素的方法如下表:

列表插入元素的方法
方法 功能
InsertAfter(v interface{}, mark *Element) *Element 在 mark 点之后插入元素,mark 点由其他插入函数提供
InsertBefore(v interface{}, mark *Element) *Element 在 mark 点之前插入元素,mark 点由其他插入函数提供
PushBackList(other *List) 添加 other 列表元素到尾部
PushFrontList(other *List) 添加 other 列表元素到头部

1.4、从列表中删除元素,遍历列表并打印

  列表的插入函数的返回值会提供一个 *list.Element 结构,这个结构记录着列表元素的值及和其他节点之间关系等信息。从列表中删除元素时,需要用到这个结构进行快速删除。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
package main
 
import (
    "container/list"
    "fmt"
)
 
func main() {
    l := list.New()
 
    //尾部添加
    l.PushBack("canon")
 
    //头部添加
    l.PushFront(67)
 
    //尾部添加后保存元素句柄
    element := l.PushBack("first")
 
    //在 first 之后添加 high
    l.InsertAfter("high", element)
 
    //在 first 之前添加 moon
    l.InsertBefore("moon", element)
 
    //遍历列表
    for i := l.Front(); i != nil; i = i.Next() {
        fmt.Println(i.Value)
    }
 
    //使用
    l.Remove(element)
 
    //遍历列表
    for i := l.Front(); i != nil; i = i.Next() {
        fmt.Println(i.Value)
    }
}

posted @   左扬  阅读(793)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
levels of contents
点击右上角即可分享
微信分享提示