container/list是一个双向链表,以下是list的定义与使用
双向链表的结构定义
// Element is an element of a linked list.
type Element struct {
// Next and previous pointers in the doubly-linked list of elements.
// To simplify the implementation, internally a list l is implemented
// as a ring, such that &l.root is both the next element of the last
// list element (l.Back()) and the previous element of the first list
// element (l.Front()).
next, prev *Element
// The list to which this element belongs.
list *List
// The value stored with this element.
Value interface{}
}
// List represents a doubly linked list.
// The zero value for List is an empty list ready to use.
type List struct {
root Element // sentinel list element, only &root, root.prev, and root.next are used
len int // current list length excluding (this) sentinel element
}
相应方法
func (e *Element) Next() *Element //返回链表中e的下一个元素
func (e *Element) Prev() *Element //返回链表中e的上一个元素
func (l *List) Init() *List //初始化或重置list
func New() *List //创建List对象
func (l *List) Len() int //元素个数
func (l *List) Front() *Element //返回第一个元素,如果list为空返回nil
func (l *List) Back() *Element //返回最后一个元素,如果list为空返回nil
func (l *List) Remove(e *Element) interface{} //移除e元素
func (l *List) PushFront(v interface{}) *Element //将v封装成*Element并插入到list的最前面,返回v封装的*Element
func (l *List) PushBack(v interface{}) *Element //将v封装成*Element并插入到list的最后面,返回v封装的*Element
func (l *List) InsertBefore(v interface{}, mark *Element) *Element //将v封装成*Element并插入到mark前面,返回v封装的*Element
func (l *List) InsertAfter(v interface{}, mark *Element) *Element //将v封装成*Element并插入到mark后面,返回v封装的*Element
func (l *List) MoveToFront(e *Element) //将e移到list的最前面
func (l *List) MoveToBack(e *Element) //将e移到list的最后面
func (l *List) MoveBefore(e, mark *Element) //将e移到mark前面
func (l *List) MoveAfter(e, mark *Element) //将e移到mark后面
func (l *List) PushBackList(other *List) //将other *List中的所有元素插入到l List的尾部
func (l *List) PushFrontList(other *List) //将other *List中的所有元素插入到l List的前面
*list.List的所有增删改都会调用其私有的方法插入或移除,func (l *List) insert(e, at *Element) *Element,func (l *List) remove(e *Element) *Element。也是其核心代码
链表插入元素
func (l *List) insert(e, at *Element) *Element {
n := at.next
at.next = e
e.prev = at
e.next = n
n.prev = e
e.list = l
l.len++
return e
}
链表移除元素
func (l *List) remove(e *Element) *Element {
e.prev.next = e.next
e.next.prev = e.prev
e.next = nil // avoid memory leaks
e.prev = nil // avoid memory leaks
e.list = nil
l.len--
return e
}
注意1:在获取list的最后一个元素时在执行Next()时,按道理来说应该返回的是root *Element,但是其返回的是nil,来看源码
func (e *Element) Next() *Element {
if p := e.next; e.list != nil && p != &e.list.root {
return p
}
return nil
}
如果e.next的指针和e.list.root的指针相同或者e.list(List,也就是根)为nil都返回nil
注意2:在获取list的第一个元素时在执行Prev()时,也会出现注意1的情况
示例:
import (
"container/list"
"fmt"
)
func main() {
list1 := list.New()
fmt.Println(list1.Len()) //0
fmt.Println(list1.Back()) // <nil> 注意1
list1.PushBack("no.1") //["no.1"]
fmt.Println(list1.Back().Value) //no.1
list1.PushBack(1) //["no.1",1]
fmt.Println(list1.Back().Value) //1
list1.PushFront(true) //[true,"no.1",1]
fmt.Println(list1.Front().Value) //true
list1.MoveToBack(list1.Front()) //["no.1",1,true]
fmt.Println(list1.Back().Value) //true
list1.MoveToFront(list1.Front().Next()) //[1,"no.1",true]
fmt.Println(list1.Front().Value) //1
fmt.Println(list1.Back().Next()) //返回nil
//list1.MoveToBack(list1.Back().Next()) //报错,(注意1)
list1.Remove(list1.Front()) //["no.1",true]
fmt.Println(list1.Front().Value) //no.1
fmt.Println(list1.Len()) //2
list1.InsertAfter(10, list1.Front()) //["no.1",10,true]
fmt.Println(list1.Front().Next().Value) //10
list1.InsertBefore(22, list1.Front()) //[22,"no.1",10,true]
fmt.Println(list1.Front().Value) //22
list1.MoveAfter(list1.Front(), list1.Back().Prev()) //["no.1",10,22,true]
fmt.Println(list1.Back().Prev().Value) //22
print(list1) //[no.1 10 22 true ]
list2 := list.New()
list2.PushBack(88)
list2.PushBack(true)
list2.PushBack("no.2")
list1.PushBackList(list2)
print(list1) //[no.1 10 22 true 88 true no.2 ]
list3 := list.New()
list3.PushBack(99)
list3.PushBack(false)
list3.PushBack("no.3")
list1.PushFrontList(list3)
print(list1) //[99 false no.3 no.1 10 22 true 88 true no.2 ]
}
func print(list *list.List) {
for p := list.Front();p != nil;p = p.Next() {
fmt.Printf("%v ",p.Value)
}
fmt.Println()
}
运行结果
0
<nil>
no.1
1
true
true
1
<nil>
no.1
2
10
22
22
no.1 10 22 true
no.1 10 22 true 88 true no.2
99 false no.3 no.1 10 22 true 88 true no.2