Golang Container包用法解析

golang Container包详解

container包含list,ring,和heap三个数据结构。其中使用heap之前需要实现对应接口。

使用heap:

其中,heap接口定义如下

type Interface interface {
   sort.Interface
   Push(x any) // add x as element Len()
   Pop() any   // remove and return element Len() - 1.
}

其中,sort的接口包含了三个方法,Len(),Less(),Swap()

type Interface interface {
   Len() int
   Less(i, j int) bool
   Swap(i, j int)
}

使用示例:

type IntHeap []int

func (h IntHeap) Len() int {
   return len(h)
}

func (h IntHeap) Less(i, j int) bool {
   return h[j] < h[i]
}

func (h IntHeap) Swap(i, j int) {
   h[i], h[j] = h[j], h[i]
}

func (h *IntHeap) Push(x interface{}) {
   *h = append(*h, x.(int))
}

func (h *IntHeap) Pop() interface{} {
   old := *h
   n := len(old)
   x := old[n-1]
   *h = old[:n-1]
   return x
}

func TestContainerHeap(t *testing.T) {
   h := &IntHeap{1, 2, 3, 4, 5, 6}
   heap.Init(h)
   fmt.Println(h)
   heap.Push(h, 3)
   fmt.Println(h)
   x := heap.Pop(h)
   fmt.Println(x)
   fmt.Println(h)
    //&[6 5 3 4 2 1]
    //&[6 5 3 4 2 1 3]
    //6
    //&[5 4 3 3 2 1]
}

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 any
}

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 TestContainerList(t *testing.T) {
   l := list.New()
   e1 := l.PushFront(1)
   l.PushFront(2)
   e3 := l.PushBack(3)
   l.InsertBefore(3, e1)
   l.InsertAfter(4, e3)
   for e := l.Front(); e != nil; e = e.Next() {
      fmt.Print(e.Value, " ")
   }
   fmt.Println()
   for e := l.Back(); e != nil; e = e.Prev() {
      fmt.Print(e.Value, " ")
   }
   fmt.Println()
   //2 3 1 3 4 
   //4 3 1 3 2 
}

Ring是一个双向链表构成的环

其结构定义如下

type Ring struct {
   next, prev *Ring
   Value      any // for use by client; untouched by this library
}

使用方法

func TestContainerRing(t *testing.T) {
   r := ring.New(10)
   for i := 0; i < 101; i++ {
      r.Value = i
      r = r.Next()
   }
   sum := 0
   r.Do(func(a any) {
      sum += a.(int)
   })
   fmt.Println("sum = ", sum, "  avg = ", sum/r.Len())
   //sum =  955   avg =  95

   fmt.Println(r.Value)
   fmt.Println(r.Len())
   //91
   //10

   r = r.Move(1)
   fmt.Println("r move 1")
   fmt.Println(r.Value)
   fmt.Println(r.Len())
   //r move 1
   //92
   //10

   r = r.Move(3)
   fmt.Println("r move 3")
   fmt.Println(r.Value)
   fmt.Println(r.Len())
   // r move 3
   //95
   //10
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值