list
- go语言中的列表采用双向链表来实现
- 实现过程中主要依赖于两个结构体,Element和List对象
- 显然list是线程不安全的包
Element详解
- Element中包含四个字段,类似于Java中的成员变量
- next为当前元素的下一个元素
- pre为当前元素的上一个元素
- &l.root为链表最后一个元素的下一个元素,同时也是链表第一个元素的上个元素,形如一个环
- list标识当前元素归属于哪个链表
- Value采用interface{}类型,可以保存任意的数据结构,也就是说go中的链表可以保存一个类似[‘abc’,12,12.03]这样的数据
|
|
- Element结构体实现了两个方法
- Next()方法返回当前节点的下一个节点数据
- Prev()方法返回当前节点的上一个节点数据
- 两个方法都屏蔽掉了list.root的情况,也就是如果找到的节点是根节点,则不做返回
|
|
List
- 链表包含两个元素
- root 根节点,只用在&root, root.prev, root.next这三种情况
- len 链表中的节点数量,不包含根节点
|
|
初始化列表
- list提供一个可外部调用的初始化方法New,实际上是调用了List的Init()方法
- Init方法返回一个空列表,也就是root的前后节点都指向自己,并且列表长度为0
|
|
Len, Front, Back方法
- Len返回list中的元素数量,获取复杂度O(1)
- Front方法返回列表第一个元素,也就是l.root.next
- Back方法返回列表最后一个元素,也就是l.root.prev
|
|
Remove方法
- Remove方法移除列表中指定元素,这个地方会对e.list做校验,如果不符合则不会进入remove方法
- remove方法完成移除元素e的操作,将e.next和e.prev设置为nil,防止内存泄露
|
|
插入操作
- lazyInit方法,懒加载,延迟初始化一个空链表
- insertValue方法是对insert的一层封装
- insert方法将节点e插入到节点at后面
- PushFront 将节点插入到root节点之后
- PushBach 将节点插入到root.prev之后
- InsertBefore 将节点插入到mark节点之前
- InsertAfter 将节点插入到mark节点之后
|
|
移动节点操作
- move为节点移动的核心方法,将节点e移动到节点at后面
- MoveToFront将节点e移动到root节点之后
- MoveToBack将节点e移动到root.prev节点之后
- MoveBefore将节点移动到mark节点之前,这个地方如果e.next == mark的时候是不需要移动的
- MoveAfter将节点移动到mark节点之后,这个地方如果mark.next == e 也是不需要移动的
|
|
列表方法
- PushBackList方法将other列表插入到l列表root.prev之后
- PushFrontList方法将other列表插入到l列表root节点之后
|
|