Go 语言的链表实现在其标准库的container/list代码包中。这个包包含了两个公开的程序实体:List和Element.
前者实现了一个双向链表(以下简称链表),而后者则代表了链表中元素的结构。
结构体类型的零值,都会拥有其特定结构,但没有初始化内容的缺省值。
var a [2]int : 包含了两个0的整数数组;
var s []int : 一个 []int类型的、值为nil的切片
var l list.list :长度为0的链表
func New() *List 新建一个链表,并初始化链表(调用Init方法初始化)
func (l *List) Init() *List 初始化链表,或者清理链表。把链表的长度置为0。并将root的prev和next都指向自己
func (l *List) Len() int 返回链表的长度,其实就是直接返回其len属性,所以时间复杂度为O(1)
func (l *List) MoveBefore(e, mark *Element) 把给定的元素移动到另一个元素的前面。
func (l *List) MoveAfter(e, mark *Element) 把给定的元素移动到另一个元素的后面。
func (l *List) MoveToFront(e *Element) 把给定的元素移动到链表的最前端。
func (l *List) MoveToBack(e *Element) 把给定的元素移动到链表的最后端。
func (l *List) Front() *Element 获取链表最前端元素
func (l *List) Back() *Element 获取链表最后的元素
func (l *List) InsertBefore(v interface{}, mark *Element) *Element 在指定元素之前插入新元素
func (l *List) InsertAfter(v interface{}, mark *Element) *Element 在指定元素之后插入新元素
func (l *List) PushFront(v interface{}) *Element 在链表最前端插入新元素
func (l *List) PushBack(v interface{}) *Element 在链表最后端插入新元素
func (l *List) Remove(e *Element) interface{} 如果e对于的链表是l,删除l中的元素e。返回的结果一定是e中的Value
“给定的元素”都是*Element类型的,该类型是Elemeent类型的指针类型,此类型的值就是元素的指针。
ring与list的区别:
1.Ring类型的数据结构仅由它自身即可代表,而List类型则需要由它以及Element类型联合表示。
2.一个Ring类型的值严格来讲,只代表了其所属的循环链表中的一个元素,而一个List类型的值则代表了一个完整的链表。
3.在创建并初始化一个Ring值的时候,我们可以指定它包含的元素的数量,但是对于一个List,循环链表一旦被创建,其长度是不可变的
4.仅通过var r ring.Ring语句声明的r将会是一个长度为1的循环链表,而List类型的零值则是一个长度为0的链表
5.Ring值的Len方法的算法复杂度是 O(N) 的,而List值的Len方法的算法复杂度则是 O(1) 的。
练习:
package main
import (
"container/list"
"fmt"
)
func main() {
// 创建一个链表
alist := list.New()
fmt.Println("Size before : ", alist.Len())
//向链表中添加元素 在list l的末尾插入值为v的元素,并返回该元素。
alist.PushBack("a")
alist.PushBack("b")
alist.PushBack("c")
fmt.Println("Size after insert(push): ", alist.Len())
// 遍历
for e := alist.Front(); e != nil; e = e.Next() {
fmt.Println(e.Value.(string))
}
//移除元素
alist.Remove(alist.Front())
alist.Remove(alist.Front())
alist.Remove(alist.Front())
fmt.Println("Size after remove(pop) : ", alist.Len())
}
源码中,链表的结构和部分方法:
type Element struct {
next, prev *Element
list *List
Value interface{}
}
// Next returns the next list element or nil.
func (e *Element) Next() *Element {
if p := e.next; e.list != nil && p != &e.list.root {
return p
}
return nil
}
// Prev returns the previous list element or nil.
func (e *Element) Prev() *Element {
if p := e.prev; e.list != nil && p != &e.list.root {
return p
}
return nil
}
// 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
}
// Init initializes or clears list l.
func (l *List) Init() *List {
l.root.next = &l.root
l.root.prev = &l.root
l.len = 0
return l
}
// New returns an initialized list.
func New() *List { return new(List).Init() }
// Len returns the number of elements of list l.
// The complexity is O(1).
func (l *List) Len() int { return l.len }
// Front returns the first element of list l or nil.
func (l *List) Front() *Element {
if l.len == 0 {
return nil
}
return l.root.next
}
// Back returns the last element of list l or nil.
func (l *List) Back() *Element {
if l.len == 0 {
return nil
}
return l.root.prev
}
// lazyInit lazily initializes a zero List value.
func (l *List) lazyInit() {
if l.root.next == nil {
l.Init()
}
}