go源码阅读

相比于List,环的结构有些特殊,环的头部就是尾部,所以每个元素可以代表自身这个环。

环其实是一个双向回环链表。
type Ring struct { next, prev *Ring Value interface{} // for use by client; untouched by this library }

// 元素可以代表自身的环
func (r *Ring) init() *Ring {
r.next = r
r.prev = r
return r
}
func New(n int) *Ring {
if n <= 0 {
return nil
}
// 创建环的头结点
r := new(Ring)
p := r
// 创建剩下的n - 1 个节点
for i := 1; i < n; i++ {
// 创建p的下一个节点,同时将下一个节点的前驱节点设置为 p
p.next = &Ring{prev: p}
// 继续创建p.next的下一个节点
p = p.next
}
// 环的最后一个节点和头结点串起来
p.next = r
r.prev = p
return r
}

// Do calls function f on each element of the ring, in forward order.
// The behavior of Do is undefined if f changes *r.
// 对环上的每一个节点应用 f() 函数
func (r *Ring) Do(f func(interface{})) {
if r != nil {
f(r.Value)
for p := r.Next(); p != r; p = p.next {
f(p.Value)
}
}
}

// 获取环中元素的个数
func (r *Ring) Len() int {
n := 0
if r != nil {
n = 1
for p := r.Next(); p != r; p = p.next {
n++
}
}
return n
}
// 链接两个环为一个环
func (r *Ring) Link(s *Ring) *Ring {
   n := r.Next()
if s != nil {
p := s.Prev()
// Note: Cannot use multiple assignment because
// evaluation order of LHS is not specified.
r.next = s
s.prev = r
n.prev = p
p.next = n
}
return n
}

// r指针从环 的r元素的位置向前或向后移动n个元素,整个环保持不变。
func (r *Ring) Move(n int) *Ring {
if r.next == nil {
return r.init()
}
switch {
case n < 0:
for ; n < 0; n++ {
r = r.prev
}
case n > 0:
for ; n > 0; n-- {
r = r.next
}
}
return r
}
// 删除从r开始的n个元素
func (r *Ring) Unlink(n int) *Ring {
if n <= 0 {
return nil
}
return r.Link(r.Move(n + 1))
}
// Next returns the next ring element. r must not be empty.
func (r *Ring) Next() *Ring {
if r.next == nil {
return r.init()
}
return r.next
}

// Prev returns the previous ring element. r must not be empty.
func (r *Ring) Prev() *Ring {
if r.next == nil {
return r.init()
}
return r.prev
}


 
原文地址:https://www.cnblogs.com/juanmaofeifei/p/14677706.html