Пакет ring реализует операции с круговыми списками.
Тип Ring
type Ring struct {
Value interface{} // для использования клиентом;
// нетронутый этой библиотекой
// содержит отфильтрованные
// или неэкспортированные поля
}
Ring - это элемент кругового списка или кольца. У колец нет начала и конца; указатель на любой элемент кольца служит ссылкой на все кольцо. Пустые кольца представлены как nil указатели на Ring. Нулевое значение для Ring - это одноэлементное кольцо с nil Value.
Функция New
func New(n int) *Ring
New создает кольцо из n элементов.
Метод Do
func (r *Ring) Do(f func(interface{}))
Do вызывает функцию f для каждого элемента кольца в прямом порядке. Поведение Do не определено, если f изменяет *r.
Пример использования Do
package main
import (
"container/ring"
"fmt"
)
func main() {
// Создаем новое кольцо размером 5
r := ring.New(5)
// Получаем длину кольца
n := r.Len()
// Инициализируем кольцо
// некоторыми целочисленными значениями
for i := 0; i < n; i++ {
r.Value = i
r = r.Next()
}
// Обходим кольцо и распечатываем его содержимое
r.Do(func(p interface{}) {
fmt.Println(p.(int))
})
}
Вывод:
0
1
2
3
4
Метод Len
func (r *Ring) Len() int
Len вычисляет количество элементов в кольце r. По времени выполняется пропорционально количеству элементов.
Пример использования Len
package main
import (
"container/ring"
"fmt"
)
func main() {
// Создаем новое кольцо размером 4
r := ring.New(4)
// Печатаем его длину
fmt.Println(r.Len())
}
Вывод:
4
Метод Link
func (r *Ring) Link(s *Ring) *Ring
Link соединяет кольцо r с кольцом s, так что r.Next() становится s и возвращает исходное значение для r.Next(). r не должно быть пустым.
Если r и s указывают на одно и то же кольцо, их связывание удаляет элементы между r и s из кольца. Удаленные элементы образуют вложенное кольцо, и результатом является ссылка на это вложенное кольцо (если элементы не были удалены, результатом все равно будет исходное значение для r.Next(), а не nil).
Если r и s указывают на разные кольца, их связывание создает одно кольцо с элементами s, вставленными после r. Результат указывает на элемент, следующий за последним элементом s после вставки.
Пример использования Link
package main
import (
"container/ring"
"fmt"
)
func main() {
// Создаем два кольца, r и s, размера 2
r := ring.New(2)
s := ring.New(2)
// Получаем длину кольца
lr := r.Len()
ls := s.Len()
// Инициализируем r нулями
for i := 0; i < lr; i++ {
r.Value = 0
r = r.Next()
}
// Инициализируем s единицами
for j := 0; j < ls; j++ {
s.Value = 1
s = s.Next()
}
// Связать кольцо r и кольцо s
rs := r.Link(s)
// Обходим объединенное кольцо
// и распечатываем его содержимое
rs.Do(func(p interface{}) {
fmt.Println(p.(int))
})
}
Вывод:
0
0
1
1
Метод Move
func (r *Ring) Move(n int) *Ring
Move перемещает n % r.Len() элементов назад (n < 0) или вперед (n >= 0) по кольцу и возвращает этот элемент кольца. r не должно быть пустым.
Пример использования Move
package main
import (
"container/ring"
"fmt"
)
func main() {
// Создаем новое кольцо размером 5
r := ring.New(5)
// Получаем длину кольца
n := r.Len()
// Инициализируем кольцо
// некоторыми целочисленными значениями
for i := 0; i < n; i++ {
r.Value = i
r = r.Next()
}
// Перемещаем указатель вперед на три шага
r = r.Move(3)
// Обходим кольцо и распечатываем его содержимое
r.Do(func(p interface{}) {
fmt.Println(p.(int))
})
}
Вывод:
3
4
0
1
2
Метод Next
func (r *Ring) Next() *Ring
Next возвращает следующий элемент кольца. r не должно быть пустым.
Пример использования Next
package main
import (
"container/ring"
"fmt"
)
func main() {
// Создаем новое кольцо размером 5
r := ring.New(5)
// Получаем длину кольца
n := r.Len()
// Инициализируем кольцо
// некоторыми целочисленными значениями
for i := 0; i < n; i++ {
r.Value = i
r = r.Next()
}
// Обходим кольцо и распечатываем его содержимое
for j := 0; j < n; j++ {
fmt.Println(r.Value)
r = r.Next()
}
}
Вывод:
0
1
2
3
4
Метод Prev
func (r *Ring) Prev() *Ring
Prev возвращает предыдущий элемент кольца. r не должно быть пустым.
Пример использования Prev
package main
import (
"container/ring"
"fmt"
)
func main() {
// Создаем новое кольцо размером 5
r := ring.New(5)
// Получаем длину кольца
n := r.Len()
// Инициализируем кольцо
// некоторыми целочисленными значениями
for i := 0; i < n; i++ {
r.Value = i
r = r.Next()
}
// Обходим кольцо в обратном направлении
// и распечатываем его содержимое
for j := 0; j < n; j++ {
fmt.Println(r.Value)
r = r.Prev()
}
}
Вывод:
4
3
2
1
0
Метод Unlink
func (r *Ring) Unlink(n int) *Ring
Unlink удаляет n % r.Len() элементов из кольца r, начиная с r.Next(). Если n % r.Len() == 0, r остается неизменным. Результат - удаленное подкольцо. r не должно быть пустым.
Пример использования Unlink
package main
import (
"container/ring"
"fmt"
)
func main() {
// Создаем новое кольцо размером 6
r := ring.New(6)
// Получаем длину кольца
n := r.Len()
// Инициализируем кольцо
// некоторыми целочисленными значениями
for i := 0; i < n; i++ {
r.Value = i
r = r.Next()
}
// Отключаем три элемента от r, начиная с r.Next()
r.Unlink(3)
// Обходим оставшееся кольцо
// и распечатываем его содержимое
r.Do(func(p interface{}) {
fmt.Println(p.(int))
})
}
Вывод:
0
4
5
Читайте также:
- Пакет list - двусвязный список в Golang
- Пакет heap в Golang
- Срезы в Golang: внутреннее устройство и использование
Комментариев нет:
Отправить комментарий