std/lists
SourceEditРеализация:
- одинарно связанных списков
- двусвязанных списков
- одинарно связанных колец (циклических списков)
- двусвязанных колец (циклических списков)
Основное использование
Поскольку это не имеет смысла делать иначе, указатели next и prev не скрываются от вас и могут быть непосредственно использованы для повышения эффективности.
Списки
Пример:
import std/lists var list = initDoublyLinkedList[int]() let a = newDoublyLinkedNode[int](3) b = newDoublyLinkedNode[int](7) c = newDoublyLinkedNode[int](9) list.add(a) list.add(b) list.prepend(c) assert a.next == b assert a.prev == c assert c.next == a assert c.next.next == b assert c.prev == nil assert b.next == nil
Кольца
Пример:
import std/lists var ring = initSinglyLinkedRing[int]() let a = newSinglyLinkedNode[int](3) b = newSinglyLinkedNode[int](7) c = newSinglyLinkedNode[int](9) ring.add(a) ring.add(b) ring.prepend(c) assert c.next == a assert a.next == b assert c.next.next == b assert b.next == c assert c.next.next.next == c
См. также
- модуль очередей с двумя концами для очередей с двумя концами
Импорты
- since
Типы
DoublyLinkedList[T] = object head*: DoublyLinkedNode[T] tail* {.cursor.}: DoublyLinkedNode[T]- Двусвязанный список. Source Edit
DoublyLinkedNodeObj[T] = object next*: DoublyLinkedNode[T] prev* {.cursor.}: DoublyLinkedNode[T] value*: T-
Узел двусвязанного списка.
Он состоит из поля
Source Editvalue, и указателей наnextиprev. SinglyLinkedList[T] = object head*: SinglyLinkedNode[T] tail* {.cursor.}: SinglyLinkedNode[T]- Одинарно связанный список. Source Edit
SinglyLinkedNodeObj[T] = object next*: SinglyLinkedNode[T] value*: T
-
Узел одинарно связанного списка.
Он состоит из поля
Source Editvalue, и указателя наnext.
Процедуры
proc add[T: SomeLinkedList](a: var T; b: T)
-
Добавляет неглубокую копию
bв конецa.См. также:
- addMoved proc
- addMoved proc для перемещения второго списка вместо копирования
Пример:
from std/sequtils import toSeq var a = [1, 2, 3].toSinglyLinkedList let b = [4, 5].toSinglyLinkedList a.add(b) assert a.toSeq == [1, 2, 3, 4, 5] assert b.toSeq == [4, 5] a.add(a) assert a.toSeq == [1, 2, 3, 4, 5, 1, 2, 3, 4, 5]
Source Edit proc add[T](L: var DoublyLinkedList[T]; n: DoublyLinkedNode[T])
-
Добавляет (добавляет в конец) узел
nкL. Эффективность: O(1).См. также:
- add proc для добавления значения
- prepend proc для добавления узла в начало
- prepend proc для добавления значения в начало
- remove proc для удаления узла
Пример:
var a = initDoublyLinkedList[int]() let n = newDoublyLinkedNode[int](9) a.add(n) assert a.contains(9)
Source Edit proc add[T](L: var DoublyLinkedList[T]; value: T)
-
Добавляет (добавляет в конец) значение к
L. Эффективность: O(1).См. также:
- add proc для добавления узла
- prepend proc для добавления узла в начало
- prepend proc для добавления значения в начало
- remove proc для удаления узла
Пример:
var a = initDoublyLinkedList[int]() a.add(9) a.add(8) assert a.contains(9)
Source Edit proc add[T](L: var DoublyLinkedRing[T]; n: DoublyLinkedNode[T])
-
Добавляет (добавляет в конец) узел
nкL. Эффективность: O(1).См. также:
- add proc для добавления значения
- prepend proc для добавления узла в начало
- prepend proc для добавления значения в начало
- remove proc для удаления узла
Пример:
var a = initDoublyLinkedRing[int]() let n = newDoublyLinkedNode[int](9) a.add(n) assert a.contains(9)
Source Edit proc add[T](L: var DoublyLinkedRing[T]; value: T)
-
Добавляет (добавляет в конец) значение к
L. Эффективность: O(1).См. также:
- add proc для добавления узла
- prepend proc для добавления узла в начало
- prepend proc для добавления значения в начало
- remove proc для удаления узла
Пример:
var a = initDoublyLinkedRing[int]() a.add(9) a.add(8) assert a.contains(9)
Source Edit proc add[T](L: var SinglyLinkedList[T]; n: SinglyLinkedNode[T]) {.inline.}-
Добавляет (добавляет в конец) узел
nкL. Эффективность: O(1).См. также:
- add proc для добавления значения
- prepend proc для добавления узла в начало
- prepend proc для добавления значения в начало
Пример:
var a = initSinglyLinkedList[int]() let n = newSinglyLinkedNode[int](9) a.add(n) assert a.contains(9)
Source Edit proc add[T](L: var SinglyLinkedList[T]; value: T) {.inline.}-
Добавляет (добавляет в конец) значение к
L. Эффективность: O(1).См. также:
- add proc для добавления значения
- prepend proc для добавления узла в начало
- prepend proc для добавления значения в начало
Пример:
var a = initSinglyLinkedList[int]() a.add(9) a.add(8) assert a.contains(9)
Source Edit proc add[T](L: var SinglyLinkedRing[T]; n: SinglyLinkedNode[T])
-
Добавляет (добавляет в конец) узел
nкL. Эффективность: O(1).См. также:
- add proc для добавления значения
- prepend proc для добавления узла в начало
- prepend proc для добавления значения в начало
Пример:
var a = initSinglyLinkedRing[int]() let n = newSinglyLinkedNode[int](9) a.add(n) assert a.contains(9)
Source Edit proc add[T](L: var SinglyLinkedRing[T]; value: T)
-
Добавляет (добавляет в конец) значение к
L. Эффективность: O(1).См. также:
- add proc для добавления узла
- prepend proc для добавления узла в начало
- prepend proc для добавления значения в начало
Пример:
var a = initSinglyLinkedRing[int]() a.add(9) a.add(8) assert a.contains(9)
Source Edit proc addMoved[T](a, b: var DoublyLinkedList[T])
-
Перемещает
bв конецa. Эффективность: O(1). Обратите внимание, чтоbстановится пустым после операции, если только он не имеет тот же адрес, что иa. Самодобавление приводит к циклу.См. также:
- add proc для добавления копии списка
Пример:
import std/[sequtils, enumerate, sugar] var a = [1, 2, 3].toDoublyLinkedList b = [4, 5].toDoublyLinkedList c = [0, 1].toDoublyLinkedList a.addMoved(b) assert a.toSeq == [1, 2, 3, 4, 5] assert b.toSeq == [] c.addMoved(c) let s = collect: for i, ci in enumerate(c): if i == 6: break ci assert s == [0, 1, 0, 1, 0, 1]Source Edit proc addMoved[T](a, b: var SinglyLinkedList[T])
-
Перемещает
bв конецa. Эффективность: O(1). Обратите внимание, чтоbстановится пустым после операции, если только он не имеет тот же адрес, что иa. Самодобавление приводит к циклу.См. также:
- add proc для добавления копии списка
Пример:
import std/[sequtils, enumerate, sugar] var a = [1, 2, 3].toSinglyLinkedList b = [4, 5].toSinglyLinkedList c = [0, 1].toSinglyLinkedList a.addMoved(b) assert a.toSeq == [1, 2, 3, 4, 5] assert b.toSeq == [] c.addMoved(c) let s = collect: for i, ci in enumerate(c): if i == 6: break ci assert s == [0, 1, 0, 1, 0, 1]Source Edit
proc appendMoved[T: SomeLinkedList](a, b: var T)
-
Псевдоним для
a.addMoved(b).См. также:
Исходный код Редактировать proc contains[T](L: SomeLinkedCollection[T]; value: T): bool {.inline.}-
Ищет значение в списке. Возвращает
falseесли значение не найдено, иtrueв противном случае. Это позволяет использовать операторыinиnotin.См. также:
Пример:
let a = [9, 8].toSinglyLinkedList assert a.contains(9) assert 8 in a assert(not a.contains(1)) assert 2 notin a
Исходный код Редактировать func copy[T](a: DoublyLinkedList[T]): DoublyLinkedList[T]
- Создает поверхностную копию
a.Пример:
from std/sequtils import toSeq type Foo = ref object x: int var f = Foo(x: 1) a = [f].toDoublyLinkedList let b = a.copy a.add([f].toDoublyLinkedList) assert a.toSeq == [f, f] assert b.toSeq == [f] # b isn't modified... f.x = 42 assert a.head.value.x == 42 assert b.head.value.x == 42 # ... but the elements are not deep copied let c = [1, 2, 3].toDoublyLinkedList assert $c == $c.copy
Исходный код Редактировать func copy[T](a: SinglyLinkedList[T]): SinglyLinkedList[T]
- Создает поверхностную копию
a.Пример:
from std/sequtils import toSeq type Foo = ref object x: int var f = Foo(x: 1) a = [f].toSinglyLinkedList let b = a.copy a.add([f].toSinglyLinkedList) assert a.toSeq == [f, f] assert b.toSeq == [f] # b isn't modified... f.x = 42 assert a.head.value.x == 42 assert b.head.value.x == 42 # ... but the elements are not deep copied let c = [1, 2, 3].toSinglyLinkedList assert $c == $c.copy
Исходный код Редактировать proc find[T](L: SomeLinkedCollection[T]; value: T): SomeLinkedNode[T]
-
Ищет значение в списке. Возвращает
nilесли значение не найдено.См. также:
Пример:
let a = [9, 8].toSinglyLinkedList assert a.find(9).value == 9 assert a.find(1) == nil
Исходный код Редактировать proc initDoublyLinkedList[T](): DoublyLinkedList[T]
-
Создает новый пустой двусвязный список.
Двусвязные списки инициализируются по умолчанию, поэтому явное вызов этой функции не требуется.
Пример:
let a = initDoublyLinkedList[int]()
Исходный код Редактировать proc initDoublyLinkedRing[T](): DoublyLinkedRing[T]
-
Создает новый пустой двусвязный кольцевой список.
Двусвязные кольцевые списки инициализируются по умолчанию, поэтому явное вызов этой функции не требуется.
Пример:
let a = initDoublyLinkedRing[int]()
Исходный код Редактировать proc initSinglyLinkedList[T](): SinglyLinkedList[T]
-
Создает новый пустой односвязный список.
Односвязные списки инициализируются по умолчанию, поэтому явное вызов этой функции не требуется.
Пример:
let a = initSinglyLinkedList[int]()
Исходный код Редактировать proc initSinglyLinkedRing[T](): SinglyLinkedRing[T]
-
Создает новый пустой односвязный кольцевой список.
Односвязные кольцевые списки инициализируются по умолчанию, поэтому явное вызов этой функции не требуется.
Пример:
let a = initSinglyLinkedRing[int]()
Исходный код Редактировать proc newDoublyLinkedNode[T](value: T): DoublyLinkedNode[T]
- Создает новый узел двусвязного списка с заданным
valueзначением.Пример:
let n = newDoublyLinkedNode[int](5) assert n.value == 5
Исходный код Редактировать proc newSinglyLinkedNode[T](value: T): SinglyLinkedNode[T]
- Создает новый узел односвязного списка с заданным
valueзначением.Пример:
let n = newSinglyLinkedNode[int](5) assert n.value == 5
Исходный код Редактировать
proc prepend[T: SomeLinkedList](a: var T; b: T)
-
Добавляет поверхностную копию
bв началоa.См. также:
- prependMoved proc для перемещения второго списка вместо копирования
Пример:
from std/sequtils import toSeq var a = [4, 5].toSinglyLinkedList let b = [1, 2, 3].toSinglyLinkedList a.prepend(b) assert a.toSeq == [1, 2, 3, 4, 5] assert b.toSeq == [1, 2, 3] a.prepend(a) assert a.toSeq == [1, 2, 3, 4, 5, 1, 2, 3, 4, 5]
Исходный код Редактировать proc prepend[T](L: var DoublyLinkedList[T]; n: DoublyLinkedNode[T])
-
Добавляет (в начало) узел
nвL. Эффективность: O(1).См. также:
- add proc для добавления узла в конец
- add proc для добавления значения в конец
- prepend proc для добавления значения в начало
- remove proc для удаления узла
Пример:
var a = initDoublyLinkedList[int]() let n = newDoublyLinkedNode[int](9) a.prepend(n) assert a.contains(9)
Исходный код Редактировать proc prepend[T](L: var DoublyLinkedList[T]; value: T)
-
Добавляет (в начало) значение в
L. Эффективность: O(1).См. также:
- add proc для добавления узла в конец
- add proc для добавления значения в конец
- prepend proc для добавления узла в начало
- remove proc для удаления узла
Пример:
var a = initDoublyLinkedList[int]() a.prepend(9) a.prepend(8) assert a.contains(9)
Исходный код Редактировать proc prepend[T](L: var DoublyLinkedRing[T]; n: DoublyLinkedNode[T])
-
Добавляет (в начало) узел
nвL. Эффективность: O(1).См. также:
- add proc для добавления узла в конец
- add proc для добавления значения в конец
- prepend proc для добавления значения в начало
- remove proc для удаления узла
Пример:
var a = initDoublyLinkedRing[int]() let n = newDoublyLinkedNode[int](9) a.prepend(n) assert a.contains(9)
Исходный код Редактировать proc prepend[T](L: var DoublyLinkedRing[T]; value: T)
-
Добавляет (в начало) значение в
L. Эффективность: O(1).См. также:
- add proc для добавления узла в конец
- add proc для добавления значения в конец
- prepend proc для добавления узла в начало
- remove proc для удаления узла
Пример:
var a = initDoublyLinkedRing[int]() a.prepend(9) a.prepend(8) assert a.contains(9)
Исходный код Редактировать proc prepend[T](L: var SinglyLinkedList[T]; n: SinglyLinkedNode[T]) {.inline.}-
Добавляет (в начало) узел в
L. Эффективность: O(1).См. также:
- add proc для добавления узла в конец
- add proc для добавления значения в конец
- prepend proc для добавления значения в начало
Пример:
var a = initSinglyLinkedList[int]() let n = newSinglyLinkedNode[int](9) a.prepend(n) assert a.contains(9)
Исходный код Редактировать proc prepend[T](L: var SinglyLinkedList[T]; value: T) {.inline.}-
Добавляет (в начало) узел в
L. Эффективность: O(1).См. также:
- add proc для добавления узла в конец
- add proc для добавления значения в конец
- prepend proc для добавления узла в начало
Пример:
var a = initSinglyLinkedList[int]() a.prepend(9) a.prepend(8) assert a.contains(9)
Исходный код Редактировать proc prepend[T](L: var SinglyLinkedRing[T]; n: SinglyLinkedNode[T])
-
Добавляет (в начало) узел
nвL. Эффективность: O(1).См. также:
- add proc для добавления узла в конец
- add proc для добавления значения в конец
- prepend proc для добавления значения в начало
Пример:
var a = initSinglyLinkedRing[int]() let n = newSinglyLinkedNode[int](9) a.prepend(n) assert a.contains(9)
Исходный код Редактировать proc prepend[T](L: var SinglyLinkedRing[T]; value: T)
-
Добавляет (в начало) значение в
L. Эффективность: O(1).См. также:
- add proc для добавления узла в конец
- add proc для добавления значения в конец
- prepend proc для добавления узла в начало
Пример:
var a = initSinglyLinkedRing[int]() a.prepend(9) a.prepend(8) assert a.contains(9)
Исходный код Редактировать proc prependMoved[T: SomeLinkedList](a, b: var T)
-
Перемещает
bперед головойa. Эффективность: O(1). Обратите внимание, чтоbстановится пустым после операции, если у него нет того же адреса, что и уa. Самоперемещение приводит к циклу.См. также:
- prepend proc для добавления копии списка в начало
Пример:
import std/[sequtils, enumerate, sugar] var a = [4, 5].toSinglyLinkedList b = [1, 2, 3].toSinglyLinkedList c = [0, 1].toSinglyLinkedList a.prependMoved(b) assert a.toSeq == [1, 2, 3, 4, 5] assert b.toSeq == [] c.prependMoved(c) let s = collect: for i, ci in enumerate(c): if i == 6: break ci assert s == [0, 1, 0, 1, 0, 1]Исходный код Редактировать proc remove[T](L: var DoublyLinkedList[T]; n: DoublyLinkedNode[T])
- Удаляет узел
nизL. Эффективность: O(1). Эта функция предполагает, для повышения эффективности, чтоnсодержится вL, в противном случае последствия не определены. Если список циклический, цикл сохраняется после удаления.Пример:
import std/[sequtils, enumerate, sugar] var a = [0, 1, 2].toSinglyLinkedList let n = a.head.next assert n.value == 1 a.remove(n) assert a.toSeq == [0, 2] a.remove(n) assert a.toSeq == [0, 2] a.addMoved(a) # cycle: [0, 2, 0, 2, ...] a.remove(a.head) let s = collect: for i, ai in enumerate(a): if i == 4: break ai assert s == [2, 2, 2, 2]Исходный код Редактировать proc remove[T](L: var DoublyLinkedRing[T]; n: DoublyLinkedNode[T])
- Удаляет
nизL. Эффективность: O(1). Эта функция предполагает, для повышения эффективности, чтоnсодержится вL, в противном случае последствия не определены.Пример:
var a = initDoublyLinkedRing[int]() let n = newDoublyLinkedNode[int](5) a.add(n) assert 5 in a a.remove(n) assert 5 notin a
Исходный код Редактировать proc remove[T](L: var SinglyLinkedList[T]; n: SinglyLinkedNode[T]): bool {. discardable.}- Удаляет узел
nизL. Возвращаетtrue, еслиnбыл найден вL. Эффективность: O(n); список просматривается до тех пор, пока не будет найденn. Попытка удалить элемент, не содержащийся в списке, — это пустая операция. Если список циклический, цикл сохраняется после удаления.Пример:
import std/[sequtils, enumerate, sugar] var a = [0, 1, 2].toSinglyLinkedList let n = a.head.next assert n.value == 1 assert a.remove(n) == true assert a.toSeq == [0, 2] assert a.remove(n) == false assert a.toSeq == [0, 2] a.addMoved(a) # cycle: [0, 2, 0, 2, ...] a.remove(a.head) let s = collect: for i, ai in enumerate(a): if i == 4: break ai assert s == [2, 2, 2, 2]Исходный код Редактировать func toDoublyLinkedList[T](elems: openArray[T]): DoublyLinkedList[T]
- Создает новый
DoublyLinkedListиз элементовelems.Пример:
from std/sequtils import toSeq let a = [1, 2, 3, 4, 5].toDoublyLinkedList assert a.toSeq == [1, 2, 3, 4, 5]
Исходный код Редактировать
func toDoublyLinkedRing[T](elems: openArray[T]): DoublyLinkedRing[T]
- Создаёт новый
DoublyLinkedRingиз элементовelems.Пример:
from std/sequtils import toSeq let a = [1, 2, 3, 4, 5].toDoublyLinkedRing assert a.toSeq == [1, 2, 3, 4, 5]
Исходный код Редактировать func toSinglyLinkedList[T](elems: openArray[T]): SinglyLinkedList[T]
- Создаёт новый
SinglyLinkedListиз элементовelems.Пример:
from std/sequtils import toSeq let a = [1, 2, 3, 4, 5].toSinglyLinkedList assert a.toSeq == [1, 2, 3, 4, 5]
Исходный код Редактировать func toSinglyLinkedRing[T](elems: openArray[T]): SinglyLinkedRing[T]
- Создаёт новый
SinglyLinkedRingиз элементовelems.Пример:
from std/sequtils import toSeq let a = [1, 2, 3, 4, 5].toSinglyLinkedRing assert a.toSeq == [1, 2, 3, 4, 5]
Исходный код Редактировать
Итераторы
iterator items[T](L: SomeLinkedList[T]): T
-
Возвращает каждое значение из
L.См. также:
Пример:
from std/sugar import collect from std/sequtils import toSeq let a = collect(initSinglyLinkedList): for i in 1..3: 10 * i assert toSeq(items(a)) == toSeq(a) assert toSeq(a) == @[10, 20, 30]
Исходный код Редактировать iterator items[T](L: SomeLinkedRing[T]): T
-
Возвращает каждое значение из
L.См. также:
Пример:
from std/sugar import collect from std/sequtils import toSeq let a = collect(initSinglyLinkedRing): for i in 1..3: 10 * i assert toSeq(items(a)) == toSeq(a) assert toSeq(a) == @[10, 20, 30]
Исходный код Редактировать iterator mitems[T](L: var SomeLinkedList[T]): var T
-
Возвращает каждое значение из
Lдля возможности его изменения.См. также:
Пример:
var a = initSinglyLinkedList[int]() for i in 1..5: a.add(10 * i) assert $a == "[10, 20, 30, 40, 50]" for x in mitems(a): x = 5 * x - 1 assert $a == "[49, 99, 149, 199, 249]"
Исходный код Редактировать iterator mitems[T](L: var SomeLinkedRing[T]): var T
-
Возвращает каждое значение из
Lдля возможности его изменения.См. также:
Пример:
var a = initSinglyLinkedRing[int]() for i in 1..5: a.add(10 * i) assert $a == "[10, 20, 30, 40, 50]" for x in mitems(a): x = 5 * x - 1 assert $a == "[49, 99, 149, 199, 249]"
Исходный код Редактировать iterator nodes[T](L: SomeLinkedList[T]): SomeLinkedNode[T]
-
Итерируется по каждому узлу
x. Поддерживается удаление текущего узла из списка во время обхода.См. также:
Пример:
var a = initDoublyLinkedList[int]() for i in 1..5: a.add(10 * i) assert $a == "[10, 20, 30, 40, 50]" for x in nodes(a): if x.value == 30: a.remove(x) else: x.value = 5 * x.value - 1 assert $a == "[49, 99, 199, 249]"Исходный код Редактировать iterator nodes[T](L: SomeLinkedRing[T]): SomeLinkedNode[T]
-
Итерируется по каждому узлу
x. Поддерживается удаление текущего узла из списка во время обхода.См. также:
Пример:
var a = initDoublyLinkedRing[int]() for i in 1..5: a.add(10 * i) assert $a == "[10, 20, 30, 40, 50]" for x in nodes(a): if x.value == 30: a.remove(x) else: x.value = 5 * x.value - 1 assert $a == "[49, 99, 199, 249]"Исходный код Редактировать
© 2006–2024 Andreas Rumpf
Licensed under the MIT License.
https://nim-lang.org/docs/lists.html