总结笔记自 Go语言中文网
import "container/ring"
ring 实现了环形链表的操作。
type Ring struct {
Value interface{} // 供调用者使用,本包不会操作该字段
// 包含隐藏或非导出字段
}
Ring类型代表环形链表的一个元素,同时也代表链表本身。环形链表没有头尾;指向环形链表任一元素的指针都可以作为整个环形链表看待。Ring零值是具有一个(Value字段为nil的)元素的链表。
方法
- New创建一个具有n个元素的环形链表。
func New(n int) *Ring
- Len返回环形链表中的元素个数,复杂度O(n)。
func (r *Ring) Len() int
- 返回后一个元素,r不能为空。
func (r *Ring) Next() *Ring
- 返回前一个元素,r不能为空。
func (r *Ring) Prev() *Ring
- 返回移动n个位置(n>=0向前移动,n<0向后移动)后的元素,r不能为空。
func (r *Ring) Move(n int) *Ring
- Link连接r和s,并返回r原本的后继元素r.Next()。r不能为空。
如果r和s指向同一个环形链表,则会删除掉r和s之间的元素,删掉的元素构成一个子链表,返回指向该子链表的指针(r的原后继元素);如果没有删除元素,则仍然返回r的原后继元素,而不是nil。如果r和s指向不同的链表,将创建一个单独的链表,将s指向的链表插入r后面,返回s原最后一个元素后面的元素(即r的原后继元素)。
func (r *Ring) Link(s *Ring) *Ring
- 删除链表中n % r.Len()个元素,从r.Next()开始删除。如果n % r.Len() == 0,不修改r。返回删除的元素构成的链表,r不能为空。
func (r *Ring) Unlink(n int) *Ring
- 对链表的每一个元素都执行f(正向顺序),注意如果f改变了*r,Do的行为是未定义的。
func (r *Ring) Do(f func(interface{}))
demo
package main
import (
"container/ring"
"fmt"
)
func Printing(v interface{}) {
fmt.Print(v, " ")
}
func main() {
// 创建第一个环形链表 r1
r1 := ring.New(10)
for i := 0; i < r1.Len(); i++ {
r1.Value = i
r1 = r1.Next()
}
// r1 现在指向 value为0
// 打印环形链表
r1.Do(Printing) // 0 1 2 3 4 5 6 7 8 9
fmt.Println("r1 的 Value:", r1.Value) // r1指针指向0
// 移动 3 位
fmt.Println("移动 3 位:", r1.Move(3).Value) // 3
r1.Do(Printing) // 0 1 2 3 4 5 6 7 8 9
fmt.Println(" ")
r1 = r1.Next()
r1.Do(Printing) // 1 2 3 4 5 6 7 8 9 0
fmt.Println("r1.Next() 后 r1 的 Value:", r1.Value) // r1指针指向1
// r1指针返回0
r1 = r1.Prev()
// 同一链表 Link
// 0 1 2 3 4 5 6 7 8 9 删除0和5之间的元素
shandiaode := r1.Link(r1.Move(5)) // 返回删掉的元素构成的子链
r1.Do(Printing) // 0 5 6 7 8 9
fmt.Println(" ")
shandiaode.Do(Printing) // 1 2 3 4
fmt.Println(" ")
// 创建环形链表r2
r2 := ring.New(3)
r2.Value = "a"
r2.Next().Value = "b"
r2.Prev().Value = "c"
r2.Do(Printing) // a b c
fmt.Println(" ")
// 不同链表 Link r1: 0 5 6 7 8 9 r2: a b c r1的指针现在指向0, 所以r2插到r1后面,其实就是插到0后面
r3 := r1.Link(r2)
r1.Do(Printing) // r1: 0 a b c 5 6 7 8 9
fmt.Println("\r\n", r1.Value) // 0
r2.Do(Printing) // r2: a b c 5 6 7 8 9 0
fmt.Println("\r\n", r2.Value) // a
r3.Do(Printing) // r3: 5 6 7 8 9 0 a b c
fmt.Println("\r\n", r3.Value) // 5
}