Go语言list(列表)
列表的原理可以这样理解:假设 A、B、C 三个人都有电话号码,如果 A 把号码告诉给 B,B 把号码告诉给 C,这个过程就建立了一个单链表结构,如下图所示。

图:三人单向通知电话号码形成单链表结构
如果在这个基础上,再从 C 开始将自己的号码告诉给自己所知道号码的主人,这样就形成了双链表结构,如下图所示。

图:三人相互通知电话号码形成双链表结构
那么如果需要获得所有人的号码,只需要从 A 或者 C 开始,要求他们将自己的号码发出来,然后再通知下一个人如此循环,这样就构成了一个列表遍历的过程。
如果 B 换号码了,他需要通知 A 和 C,将自己的号码移除,这个过程就是列表元素的删除操作,如下图所示。

图:从双链表中删除一人的电话号码
在Go语言中,列表使用 container/list 包来实现,内部的实现原理是双链表,列表能够高效地进行任意位置的元素插入和删除操作。
初始化列表
list 的初始化有两种方法:分别是使用 New() 函数和 var 关键字声明,两种方法的初始化效果都是一致的。1) 通过 container/list 包的 New() 函数初始化 list
变量名 := list.New()
2) 通过 var 关键字声明初始化 list
var 变量名 list.List
列表与切片和 map 不同的是,列表并没有具体元素类型的限制,因此,列表的元素可以是任意类型,这既带来了便利,也引来一些问题,例如给列表中放入了一个 interface{} 类型的值,取出值后,如果要将 interface{} 转换为其他类型将会发生宕机。
在列表中插入元素
双链表支持从队列前方或后方插入元素,分别对应的方法是 PushFront 和 PushBack。
提示
这两个方法都会返回一个 *list.Element 结构,如果在以后的使用中需要删除插入的元素,则只能通过 *list.Element 配 Remove() 方法进行删除,这种方法可以让删除更加效率化,同时也是双链表特性之一。下面代码展示如何给 list 添加元素:
l := list.New()
l.PushBack("fist")
l.PushFront(67)
代码说明如下:
第 1 行,创建一个列表实例。
第 3 行,将 fist 字符串插入到列表的尾部,此时列表是空的,插入后只有一个元素。
第 4 行,将数值 67 放入列表,此时,列表中已经存在 fist 元素,67 这个元素将被放在 fist 的前面。
列表插入元素的方法如下表所示。
方 法 | 功 能 |
|---|---|
InsertAfter(v interface {}, mark * Element) * Element | 在 mark 点之后插入元素,mark 点由其他插入函数提供 |
InsertBefore(v interface {}, mark * Element) *Element | 在 mark 点之前插入元素,mark 点由其他插入函数提供 |
PushBackList(other *List) | 添加 other 列表元素到尾部 |
PushFrontList(other *List) | 添加 other 列表元素到头部 |
从列表中删除元素
列表插入函数的返回值会提供一个 *list.Element 结构,这个结构记录着列表元素的值以及与其他节点之间的关系等信息,从列表中删除元素时,需要用到这个结构进行快速删除。列表操作元素:
代码说明如下:package main
import "container/list"
func main() {
l := list.New()
// 尾部添加
l.PushBack("canon")
// 头部添加
l.PushFront(67)
// 尾部添加后保存元素句柄
element := l.PushBack("fist")
// 在fist之后添加high
l.InsertAfter("high", element)
// 在fist之前添加noon
l.InsertBefore("noon", element)
// 使用
l.Remove(element)
}
第 6 行,创建列表实例。
第 9 行,将字符串 canon 插入到列表的尾部。
第 12 行,将数值 67 添加到列表的头部。
第 15 行,将字符串 fist 插入到列表的尾部,并将这个元素的内部结构保存到 element 变量中。
第 18 行,使用 element 变量,在 element 的位置后面插入 high 字符串。
第 21 行,使用 element 变量,在 element 的位置前面插入 noon 字符串。
第 24 行,移除 element 变量对应的元素。
下表中展示了每次操作后列表的实际元素情况。
操作内容 | 列表元素 |
|---|---|
l.PushBack("canon") | canon |
l.PushFront(67) | 67, canon |
element := l.PushBack("fist") | 67, canon, fist |
l.InsertAfter("high", element) | 67, canon, fist, high |
l.InsertBefore("noon", element) | 67, canon, noon, fist, high |
l.Remove(element) | 67, canon, noon, high |
遍历列表——访问列表的每一个元素
遍历双链表需要配 Front() 函数获取头元素,遍历时只要元素不为空就可以继续进行,每一次遍历都会调用元素的 Next() 函数,代码如下所示。
l := list.New()
// 尾部添加
l.PushBack("canon")
// 头部添加
l.PushFront(67)
for i := l.Front(); i != nil; i = i.Next() {
fmt.Println(i.Value)
}
代码输出如下:
67
canon
代码说明如下:
第 1 行,创建一个列表实例。
第 4 行,将 canon 放入列表尾部。
第 7 行,在队列头部放入 67。
第 9 行,使用 for 语句进行遍历,其中 i:=l.Front() 表示初始赋值,只会在一开始执行一次,每次循环会进行一次 i != nil 语句判断,如果返回 false,表示退出循环,反之则会执行 i = i.Next()。
第 10 行,使用遍历返回的 *list.Element 的 Value 成员取得放入列表时的原值。
- 随机文章
- 核心危机(核心危机魔石合成攻略)
- 风儿(风儿轻轻的吹)
- 饿了么红包怎么用(饿了么红包怎么用微信支付)
- 儿童教育文章(儿童教育)
- xboxones(xboxone手柄怎么配对主机)
- 兵马俑(兵马俑介绍和历史背景)
- 海猫鸣泣之时游戏(海猫鸣泣之时游戏在哪玩)
- 韩国媳妇和小雪(韩国媳妇和小雪的父亲工资是多少)
- 鬼泣5攻略(鬼泣5攻略第三关怎么跳)
- 地球日主题(2020年世界地球日主题)
- 和柳亚子(和柳亚子先生于田)
- 冰客(冰客果汁)
- yy魔兽(yy魔兽世界)
- 充值卡代理(充值卡代理加盟)
- 拆奶罩
- 东天目山(东天目山景区)
- 杭同(杭同培训中心怎么样)
- 大松电饭煲(美的大松电饭煲)
- 疯狂填字(疯狂填字5)
- 点对点短信息(点对点短信息费是什么意思)
- 河北省大运会(河北省大运会时间)
- 哈利波特官网(哈利波特官网在哪里)
- 骇客神条(骇客神条怎么辨别真假)
- 杜星霖(杜星霖图片)
- 查传倜(查传倜个人生活)
- 广州晓港公园(广州晓港公园正门图片)
- 常州天宁寺(常州天宁寺求什么灵验)
- 河源巴伐利亚(河源巴伐利亚庄园)
- 防水地板(防水复合地板)
- 岗位能力证书(岗位能力证书有用吗)
