一.双向循环链表

  • 循环链表特点是没有节点的指针域为nil,通过任何一个元素都可以找到其他元素
  • 环形链表结构如下
  • 双向循环链表和双向链表区别

    • 双向循环链表没有严格意义上的头元素和尾元素
    • 没有元素的前连接和后连接为nil
    • 一个长度为n的双向循环链表,通过某个元素向某个方向移动,在查找最多n-1次后一定会找到另一个元素

      二.Go语言中的双向循环链表

  • 在container/ring包下结构体Ring源码如下

    • 官方明确说明了Ring是循环链表的元素,又是环形链表.
    • 实际使用时Ring遍历就是环形链表第一个元素
      1. // A Ring is an element of a circular list, or ring.
      2. // Rings do not have a beginning or end; a pointer to any ring element
      3. // serves as reference to the entire ring. Empty rings are represented
      4. // as nil Ring pointers. The zero value for a Ring is a one-element
      5. // ring with a nil Value.
      6. //
      7. type Ring struct {
      8. next, prev *Ring
      9. Value interface{} // for use by client; untouched by this library
      10. }
  • Go语言标准库中对container/ring包提供的API如下

    1. type Ring
    2. //实例化长度为n的环形链表
    3. func New(n int) *Ring
    4. //长度
    5. func (r *Ring) Len() int
    6. //下一个元素
    7. func (r *Ring) Next() *Ring
    8. //上一个元素
    9. func (r *Ring) Prev() *Ring
    10. //移动n次,支持负数
    11. func (r *Ring) Move(n int) *Ring
    12. //合并s和r
    13. func (r *Ring) Link(s *Ring) *Ring
    14. //删除r后面n%r.Len()元素,删除多个,当前元素前面的不删除
    15. func (r *Ring) Unlink(n int) *Ring
    16. //循环遍历,i是当前元素的值
    17. func (r *Ring) Do(f func(interface{}))

三.代码演示

  • 实例化、赋值、遍历

    1. r := ring.New(3)
    2. for i := 0; i < r.Len(); i++ {
    3. r.Move(i).Value = i
    4. }
    5. r.Do(func(i interface{}) {
    6. fmt.Println(i)
    7. })
  • 实例化后的r就是链表中第一个创建的元素.可以找到元素的前后元素

    1. fmt.Println(r.Next().Value)//输出:1
    2. fmt.Println(r.Next().Next().Value)//输出:2
    3. fmt.Println(r.Next().Next().Next().Value)//输出:0
    4. fmt.Println(r.Move(-1).Value)//输出:2
    5. fmt.Println(r.Prev().Value)//输出:2
  • 可以向环形链表添加或删除链表

    1. s := ring.New(1)
    2. s.Value = 13
    3. //r是哪个元素,就把新的链表添加到哪个元素后面
    4. r.Link(s)
    5. r.Do(func(i interface{}) {
    6. fmt.Print(i, " ")
    7. })
    8. fmt.Println("")
    9. //从r元素向后,n/r.Len()个元素被删除,当前元素和前面的保留
    10. r.Unlink(1)
    11. r.Do(func(i interface{}) {
    12. fmt.Print(i, " ")
    13. })