类似于Java的集合:list,map,set等,Go语言中也提供了类似的标准容器,在标准包container包含了conatiner/list,container/heap,container/ring三种标准容器。
(1)conatiner/list 容器
在conatiner/list源码包中提供了相关的示例,比如下面这个示例
package list_test
import (
"container/list"
"fmt"
)
func Example() {
// 创建一个新list并在其中放入一些数字。
l := list.New()
e4 := l.PushBack(4)
e1 := l.PushFront(1)
l.InsertBefore(3, e4)
l.InsertAfter(2, e1)
// Iterate through list and print its contents.
for e := l.Front(); e != nil; e = e.Next() {
fmt.Println(e.Value)
}
}
list是一个双向的链表,可以添加类型不一的元素进来,它的相关类型说明如下所示:
// 表示列表中的元素
type Element struct {
//双向链接元素列表中的下一个和前一个指针。
next, prev *Element
//此元素所属的列表。
list *List
// 使用此元素存储的值。
Value interface{}
}
// List表示双向链表。
// List的零值是一个可供使用的空列表。
type List struct {
root Element // //列出代表列表元素,仅使用&root,root.prev和root.next
len int //当前列表长度不包括(this)sentinel元素
}
初始化函数说明如下所示:
//New返回初始化列表。
func New() *List { return new(List).Init() }
// Init初始化或清除列表l。
func (l *List) Init() *List {
l.root.next = &l.root
l.root.prev = &l.root
l.len = 0
return l
}
添加元素函数说明:可以添加类型不一的元素进来:
// 追加新元素到末尾,返回该元素指针
func (l *List) PushBack(v interface{}) *Element
// 追加另一个列表到末尾
func (l *List) PushBackList(other *List)
// 添加新元素到开头,返回该元素指针
func (l *List) PushFront(v interface{}) *Element
// 添加另一个列表到开头
func (l *List) PushFrontList(other *List)
// 在mark后面插入新元素,返回新元素指针
func (l *List) InsertAfter(v interface{}, mark *Element) *Element
// 在mark前插入新元素,返回新元素指针
func (l *List) InsertBefore(v interface{}, mark *Element) *Element
移除元素函数说明:e和mark都必须是l的内的元素,否则该函数不执行任何动作
// 移动e到mark之后
func (l *List) MoveAfter(e, mark *Element)
// 移动e到mark之前
func (l *List) MoveBefore(e, mark *Element)
// 移动e到末尾
func (l *List) MoveToBack(e *Element)
// 移动e到开头
func (l *List) MoveToFront(e *Element)
// 移除e,返回e的值
func (l *List) Remove(e *Element) interface{}
访问元素函数说明:
// 返回结尾元素
func (l *List) Back() *Element
// 返回开头元素
func (l *List) Front() *Element
遍历函数说明:
// Len返回列表l的元素数。
//复杂性是O(1)。
func (l *List) Len() int { return l.len }
// Next返回下一个列表元素或nil。
func (e *Element) Next() *Element
// Prev返回上一个列表元素或nil。
func (e *Element) Prev() *Element
(2)conatiner/ ring 容器
关于ring 容器的函数说明与结构如下所示:
// Ring是循环列表或循环的元素。
type Ring struct {
Value interface{} // 类型为interface{},因此可以接受任意类型
}
// 创建一个长度为n的环形链表
func New(n int) *Ring
// 针对环形链表中的每一个元素x进行f(x)操作
func (r *Ring) Do(f func(interface{}))
// 获取环形链表长度
func (r *Ring) Len() int
// 如果r和s在同一环形链表中,则删除r和s之间的元素
// 被删除的元素组成一个新的环形链表,返回值为该环形链表的指针(即删除前,r->Next()表示的元素)
// 如果r和s不在同一个环形链表中,则将s插入到r后面,返回值为 插入s后,s最后一个元素的下一个元素(即插入前,r->Next()表示的元素)
func (r *Ring) Link(s *Ring) *Ring
// 移动 n % r.Len() 个位置,n正负均可
func (r *Ring) Move(n int) *Ring
// 返回下一个元素
func (r *Ring) Next() *Ring
// 返回前一个元素
func (r *Ring) Prev() *Ring
// 删除r后面的 n % r.Len() 个元素
func (r *Ring) Unlink(n int) *Ring
(3)conatiner/ heap 容器
conatiner/ heap 容器仅仅提供了最小堆的操作,然后由我们自己实现堆的数据结构(必须满足heap定义的接口),再利用heap包提供了一个heap.Interface接口做桥梁跟堆的操作搭上关系。
堆数据结构满足的接口定义:
type Interface interface {
sort.Interface
Push(x interface{}) // 将x添加为元素Len()
Pop() interface{} // 移除并返回元素的Len() - 1
}
而 sort.Interface 的接口定义如下:
type Interface interface {
// Len is the number of elements in the collection.
Len() int
// Less reports whether the element with
// index i should sort before the element with index j.
Less(i, j int) bool
// Swap swaps the elements with indexes i and j.
Swap(i, j int)
}
也就是说,如果我们让堆的数据结构与heap提供的堆操作搭上关系,就必须实现上面的五个方法。
heap包中还提供了下面几个函数的实现:
//必须先初始化堆,然后才能使用任何堆操作。 Init对于堆不变量是幂等的,并且可以在堆不变量可能被无效时被调用。
//其复杂度为O(n),其中n = h.Len()。
func Init(h Interface)
// Push将元素x推送到堆上。 复杂度为O(log(n)),其中n = h.Len()。
func Push(h Interface, x interface{})
// Pop从堆中删除最小元素(根据Less)并返回它。 复杂度为O(log(n)),其中n = h.Len()。
//相当于Remove(h,0)。
func Pop(h Interface) interface{}
// Remove从堆中删除索引i处的元素。
//复杂度为O(log(n)),其中n = h.Len()。
func Remove(h Interface, i int)
//修复在索引i处的元素更改其值后重新建立堆排序。
//在索引i处更改元素的值,然后调用Fix,相当于调用Remove(h,i),然后调用新值,相当于便宜。
//复杂度为O(log(n)),其中n = h.Len()。
func Fix(h Interface, i int)
func up(h Interface, j int)
func down(h Interface, i0, n int) bool