這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
今天,Mayuyu來介紹Go語言中一個重要的東西,叫做container。具體源碼可以參考Go語言的原始碼,如下
路徑:/usr/local/go/src/pkg/container
Github上的路徑為:https://github.com/astaxie/gopkg/tree/master/container
container的結構如下
可以看出包含三部分:heap,list和ring。下面分別介紹
1. heap
heap即為堆,是一種常用的資料結構,在源碼裡面,提供了介面,在實際使用時需要實現。
下面是一個關於heap使用的執行個體。
代碼:
package mainimport ("fmt""container/heap")//heap提供了介面,需要自己實現如下方法type Heap []int//構造的是小頂堆,大頂堆只需要改一下下面的符號func (h *Heap) Less(i, j int) bool {return (*h)[i] < (*h)[j]}func (h *Heap) Swap(i, j int) {(*h)[i], (*h)[j] = (*h)[j], (*h)[i]}func (h *Heap) Len() int {return len(*h)}func (h *Heap) Pop() interface{} {x := (*h)[h.Len() - 1]*h = (*h)[: h.Len() - 1]return x}func (h *Heap) Push(x interface{}) {*h = append(*h, x.(int))}func (h *Heap) Remove(idx int) interface{} {h.Swap(idx, h.Len() - 1)return h.Pop()}func main(){//建立一個heaph := &Heap{} heap.Init(h)//向heap中插入元素h.Push(5)h.Push(2)h.Push(1)h.Push(8)h.Push(4)h.Push(6)h.Push(2)//輸出heap中的元素,相當於一個數組,原始數組fmt.Println(h)//這裡必須要reheapify,建立好堆了heap.Init(h)//小頂堆對應的元素在數組中的位置fmt.Println(h)//移除下標為5的元素,下標從0開始h.Remove(5)//按照堆的形式輸出for h.Len() > 0 {fmt.Printf("%d ", heap.Pop(h))}fmt.Println()}
2. list
list類型是雙向鏈表,具體用法如下
代碼:
package mainimport ("fmt""container/list")func main(){//建立一個雙向鏈表ls := list.New()//向雙向鏈表中插入26個小寫字母for i := 97; i < 123; i++ {ls.PushFront(i) //PushFront()代表從頭部插入,同樣PushBack()代表從尾部插入}//遍曆雙向鏈表ls中的所有字母for it := ls.Front(); it != nil; it = it.Next() {fmt.Printf("%c ", it.Value)}fmt.Println()}
3. ring
ring是一個環形鏈表,具體用法可以參考如下代碼
代碼:
package mainimport ("fmt""container/ring"//閉環包引入,詳見/usr/local/go/src/pkg/container/ring)func main(){//建立10個元素的閉環r := ring.New(10)//給閉環中的元素賦值for i := 1; i <= r.Len(); i++ {r.Value = ir = r.Next()} //迴圈列印閉環中的元素值r.Do(func(p interface{}){println(p) })//獲得當前元素之後的第5個元素r5 := r.Move(5)fmt.Println(r5)fmt.Println(r)//連結當前元素r與r5,相當於刪除了r與r5之間的元素r1 := r.Link(r5)fmt.Println(r1)fmt.Println(r)}