Implementation of:
Because it makes no sense to do otherwise, the next and prev pointers are not hidden from you and can be manipulated directly for efficiency.
Example:
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
Example:
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
DoublyLinkedList[T] = object
head*: DoublyLinkedNode[T]
tail* {.cursor.}: DoublyLinkedNode[T]DoublyLinkedNodeObj[T] = object
next*: DoublyLinkedNode[T]
prev* {.cursor.}: DoublyLinkedNode[T]
value*: TA node of a doubly linked list.
It consists of a value field, and pointers to next and prev.
SinglyLinkedList[T] = object
head*: SinglyLinkedNode[T]
tail* {.cursor.}: SinglyLinkedNode[T]SinglyLinkedNodeObj[T] = object next*: SinglyLinkedNode[T] value*: T
A node of a singly linked list.
It consists of a value field, and a pointer to next.
proc add[T: SomeLinkedList](a: var T; b: T)
Appends a shallow copy of b to the end of a.
See also:
Example:
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])
Appends (adds to the end) a node n to L. Efficiency: O(1).
See also:
Example:
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)
Appends (adds to the end) a value to L. Efficiency: O(1).
See also:
Example:
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])
Appends (adds to the end) a node n to L. Efficiency: O(1).
See also:
Example:
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)
Appends (adds to the end) a value to L. Efficiency: O(1).
See also:
Example:
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.}Appends (adds to the end) a node n to L. Efficiency: O(1).
See also:
Example:
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.}Appends (adds to the end) a value to L. Efficiency: O(1).
See also:
Example:
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])
Appends (adds to the end) a node n to L. Efficiency: O(1).
See also:
Example:
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)
Appends (adds to the end) a value to L. Efficiency: O(1).
See also:
Example:
var a = initSinglyLinkedRing[int]() a.add(9) a.add(8) assert a.contains(9)Source Edit
proc addMoved[T](a, b: var DoublyLinkedList[T])
Moves b to the end of a. Efficiency: O(1). Note that b becomes empty after the operation unless it has the same address as a. Self-adding results in a cycle.
See also:
Example:
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])
Moves b to the end of a. Efficiency: O(1). Note that b becomes empty after the operation unless it has the same address as a. Self-adding results in a cycle.
See also:
Example:
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 contains[T](L: SomeLinkedCollection[T]; value: T): bool {.inline.}Searches in the list for a value. Returns false if the value does not exist, true otherwise. This allows the usage of the in and notin operators.
See also:
Example:
let a = [9, 8].toSinglyLinkedList assert a.contains(9) assert 8 in a assert(not a.contains(1)) assert 2 notin aSource Edit
func copy[T](a: DoublyLinkedList[T]): DoublyLinkedList[T]
a. Example:
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.copySource Edit
func copy[T](a: SinglyLinkedList[T]): SinglyLinkedList[T]
a. Example:
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.copySource Edit
proc prepend[T: SomeLinkedList](a: var T; b: T)
Prepends a shallow copy of b to the beginning of a.
See also:
Example:
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]Source Edit
proc prepend[T](L: var DoublyLinkedList[T]; n: DoublyLinkedNode[T])
Prepends (adds to the beginning) a node n to L. Efficiency: O(1).
See also:
Example:
var a = initDoublyLinkedList[int]() let n = newDoublyLinkedNode[int](9) a.prepend(n) assert a.contains(9)Source Edit
proc prepend[T](L: var DoublyLinkedList[T]; value: T)
Prepends (adds to the beginning) a value to L. Efficiency: O(1).
See also:
Example:
var a = initDoublyLinkedList[int]() a.prepend(9) a.prepend(8) assert a.contains(9)Source Edit
proc prepend[T](L: var DoublyLinkedRing[T]; n: DoublyLinkedNode[T])
Prepends (adds to the beginning) a node n to L. Efficiency: O(1).
See also:
Example:
var a = initDoublyLinkedRing[int]() let n = newDoublyLinkedNode[int](9) a.prepend(n) assert a.contains(9)Source Edit
proc prepend[T](L: var DoublyLinkedRing[T]; value: T)
Prepends (adds to the beginning) a value to L. Efficiency: O(1).
See also:
Example:
var a = initDoublyLinkedRing[int]() a.prepend(9) a.prepend(8) assert a.contains(9)Source Edit
proc prepend[T](L: var SinglyLinkedList[T]; n: SinglyLinkedNode[T]) {.inline.}Prepends (adds to the beginning) a node to L. Efficiency: O(1).
See also:
Example:
var a = initSinglyLinkedList[int]() let n = newSinglyLinkedNode[int](9) a.prepend(n) assert a.contains(9)Source Edit
proc prepend[T](L: var SinglyLinkedList[T]; value: T) {.inline.}Prepends (adds to the beginning) a node to L. Efficiency: O(1).
See also:
Example:
var a = initSinglyLinkedList[int]() a.prepend(9) a.prepend(8) assert a.contains(9)Source Edit
proc prepend[T](L: var SinglyLinkedRing[T]; n: SinglyLinkedNode[T])
Prepends (adds to the beginning) a node n to L. Efficiency: O(1).
See also:
Example:
var a = initSinglyLinkedRing[int]() let n = newSinglyLinkedNode[int](9) a.prepend(n) assert a.contains(9)Source Edit
proc prepend[T](L: var SinglyLinkedRing[T]; value: T)
Prepends (adds to the beginning) a value to L. Efficiency: O(1).
See also:
Example:
var a = initSinglyLinkedRing[int]() a.prepend(9) a.prepend(8) assert a.contains(9)Source Edit
proc prependMoved[T: SomeLinkedList](a, b: var T)
Moves b before the head of a. Efficiency: O(1). Note that b becomes empty after the operation unless it has the same address as a. Self-prepending results in a cycle.
See also:
Example:
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] Source Edit proc remove[T](L: var DoublyLinkedList[T]; n: DoublyLinkedNode[T])
n from L. Efficiency: O(1). This function assumes, for the sake of efficiency, that n is contained in L, otherwise the effects are undefined. When the list is cyclic, the cycle is preserved after removal. Example:
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] Source Edit proc remove[T](L: var DoublyLinkedRing[T]; n: DoublyLinkedNode[T])
n from L. Efficiency: O(1). This function assumes, for the sake of efficiency, that n is contained in L, otherwise the effects are undefined. Example:
var a = initDoublyLinkedRing[int]() let n = newDoublyLinkedNode[int](5) a.add(n) assert 5 in a a.remove(n) assert 5 notin aSource Edit
proc remove[T](L: var SinglyLinkedList[T]; n: SinglyLinkedNode[T]): bool {.
discardable.}n from L. Returns true if n was found in L. Efficiency: O(n); the list is traversed until n is found. Attempting to remove an element not contained in the list is a no-op. When the list is cyclic, the cycle is preserved after removal. Example:
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] Source Edit iterator items[T](L: SomeLinkedList[T]): T
Yields every value of L.
See also:
Example:
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]Source Edit
iterator mitems[T](L: var SomeLinkedList[T]): var T
Yields every value of L so that you can modify it.
See also:
Example:
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]"Source Edit
iterator mitems[T](L: var SomeLinkedRing[T]): var T
Yields every value of L so that you can modify it.
See also:
Example:
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]"Source Edit
iterator nodes[T](L: SomeLinkedList[T]): SomeLinkedNode[T]
Iterates over every node of x. Removing the current node from the list during traversal is supported.
See also:
Example:
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]" Source Edit iterator nodes[T](L: SomeLinkedRing[T]): SomeLinkedNode[T]
Iterates over every node of x. Removing the current node from the list during traversal is supported.
See also:
Example:
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]" Source Edit
© 2006–2024 Andreas Rumpf
Licensed under the MIT License.
https://nim-lang.org/docs/lists.html