Тип ring.Ring

Тип ring.Ring представляет собой кольцевой список, в котором каждый элемент (узел) содержит ссылки на следующий и предыдущий элементы. В отличие от обычного связанного списка, в кольцевом списке последний элемент ссылается на первый, а первый — на последний. Это делает структуру идеальной для задач, требующих циклического перебора данных. Основное поле типа ring.Ring — это Value типа any, которое хранит данные узла.

Создание кольцевого списка

Для создания кольцевого списка используется функция ring.New, которая принимает количество элементов и возвращает указатель на первый узел. Все элементы автоматически связываются в кольцо.

gopackage main

import (
  "container/ring"
  "fmt"
)

func main() {
  r := ring.New(5) // Создаем кольцо из 5 элементов

  for i := 0; i < r.Len(); i++ {
    r.Value = i
    r = r.Next()
  }

  r.Do(func(x any) {
    fmt.Println(x)
  })
}

Результат выполнения кода:

go0
1
2
3
4

В этом примере мы создаем кольцо из пяти элементов, заполняем их значениями и выводим все элементы с помощью метода Do.

Метод Next и Prev

Метод Next возвращает указатель на следующий элемент кольца, а метод Prev — на предыдущий. Эти методы позволяют перемещаться по кольцу в обоих направлениях.

gopackage main

import (
  "container/ring"
  "fmt"
)

func main() {
  r := ring.New(3)
  r.Value = "a"
  r = r.Next()
  r.Value = "b"
  r = r.Next()
  r.Value = "c"

  // Перемещаемся вперед
  fmt.Println(r.Next().Value)
  // Перемещаемся назад
  fmt.Println(r.Prev().Value)
}

Результат выполнения кода:

go"a"
"b"

Здесь мы создаем кольцо с тремя элементами и демонстрируем перемещение по кругу с помощью Next и Prev. Обратите внимание, что после Next мы попадаем на первый элемент, так как кольцо замкнуто.

Метод Move

Метод Move позволяет переместить указатель на заданное количество шагов. Положительное число перемещает вперед, отрицательное — назад.

gopackage main

import (
  "container/ring"
  "fmt"
)

func main() {
  r := ring.New(5)
  for i := 0; i < r.Len(); i++ {
    r.Value = i
    r = r.Next()
  }

  // Перемещаемся на 2 шага вперед
  r = r.Move(2)
  fmt.Println(r.Value)

  // Перемещаемся на 1 шаг назад
  r = r.Move(-1)
  fmt.Println(r.Value)
}

Результат выполнения кода:

go2
1

В этом примере мы создаем кольцо из пяти элементов, заполняем их, затем перемещаемся на два шага вперед и на один шаг назад, выводя значения на каждой позиции.

Метод Len

Метод Len возвращает количество элементов в кольцевом списке. Это полезно для проверки размера кольца перед выполнением операций.

gopackage main

import (
  "container/ring"
  "fmt"
)

func main() {
  r := ring.New(4)
  fmt.Println("Length:", r.Len())
}

Результат выполнения кода:

go"Length: 4"

Метод Len возвращает длину кольца, которая была задана при создании.

Смотрите также

  • метод ring.Ring.Next,
    который возвращает следующий элемент кольца
  • метод ring.Ring.Prev,
    который возвращает предыдущий элемент кольца
  • метод ring.Ring.Move,
    который перемещает указатель на заданное количество шагов
  • метод ring.Ring.Do,
    который применяет функцию ко всем элементам кольца