Source Edit

Implementation of:

Basic Usage

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.

Lists

Example:

  1. import std/lists
  2. var list = initDoublyLinkedList[int]()
  3. let
  4. a = newDoublyLinkedNode[int](3)
  5. b = newDoublyLinkedNode[int](7)
  6. c = newDoublyLinkedNode[int](9)
  7. list.add(a)
  8. list.add(b)
  9. list.prepend(c)
  10. assert a.next == b
  11. assert a.prev == c
  12. assert c.next == a
  13. assert c.next.next == b
  14. assert c.prev == nil
  15. assert b.next == nil

Rings

Example:

  1. import std/lists
  2. var ring = initSinglyLinkedRing[int]()
  3. let
  4. a = newSinglyLinkedNode[int](3)
  5. b = newSinglyLinkedNode[int](7)
  6. c = newSinglyLinkedNode[int](9)
  7. ring.add(a)
  8. ring.add(b)
  9. ring.prepend(c)
  10. assert c.next == a
  11. assert a.next == b
  12. assert c.next.next == b
  13. assert b.next == c
  14. assert c.next.next.next == c

See also

Imports

since

Types

  1. DoublyLinkedList[T] = object
  2. head*: DoublyLinkedNode[T]
  3. tail* {.cursor.}: DoublyLinkedNode[T]

A doubly linked list. Source Edit

  1. DoublyLinkedNode[T] = ref DoublyLinkedNodeObj[T]

Source Edit

  1. DoublyLinkedNodeObj[T] = object
  2. next*: DoublyLinkedNode[T]
  3. prev* {.cursor.}: DoublyLinkedNode[T]
  4. value*: T

A node of a doubly linked list.

It consists of a value field, and pointers to next and prev.

Source Edit

  1. DoublyLinkedRing[T] = object
  2. head*: DoublyLinkedNode[T]

A doubly linked ring. Source Edit

  1. SinglyLinkedList[T] = object
  2. head*: SinglyLinkedNode[T]
  3. tail* {.cursor.}: SinglyLinkedNode[T]

A singly linked list. Source Edit

  1. SinglyLinkedNode[T] = ref SinglyLinkedNodeObj[T]

Source Edit

  1. SinglyLinkedNodeObj[T] = object
  2. next*: SinglyLinkedNode[T]
  3. value*: T

A node of a singly linked list.

It consists of a value field, and a pointer to next.

Source Edit

  1. SinglyLinkedRing[T] = object
  2. head*: SinglyLinkedNode[T]
  3. tail* {.cursor.}: SinglyLinkedNode[T]

A singly linked ring. Source Edit

  1. SomeLinkedCollection[T] = SomeLinkedList[T] | SomeLinkedRing[T]

Source Edit

  1. SomeLinkedList[T] = SinglyLinkedList[T] | DoublyLinkedList[T]

Source Edit

  1. SomeLinkedNode[T] = SinglyLinkedNode[T] | DoublyLinkedNode[T]

Source Edit

  1. SomeLinkedRing[T] = SinglyLinkedRing[T] | DoublyLinkedRing[T]

Source Edit

Procs

  1. proc `$`[T](L: SomeLinkedCollection[T]): string

Turns a list into its string representation for logging and printing.

Example:

  1. let a = [1, 2, 3, 4].toSinglyLinkedList
  2. assert $a == "[1, 2, 3, 4]"

Source Edit

  1. proc add[T: SomeLinkedList](a: var T; b: T)

Appends a shallow copy of b to the end of a.

See also:

Example:

  1. from std/sequtils import toSeq
  2. var a = [1, 2, 3].toSinglyLinkedList
  3. let b = [4, 5].toSinglyLinkedList
  4. a.add(b)
  5. assert a.toSeq == [1, 2, 3, 4, 5]
  6. assert b.toSeq == [4, 5]
  7. a.add(a)
  8. assert a.toSeq == [1, 2, 3, 4, 5, 1, 2, 3, 4, 5]

Source Edit

  1. 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:

  1. var a = initDoublyLinkedList[int]()
  2. let n = newDoublyLinkedNode[int](9)
  3. a.add(n)
  4. assert a.contains(9)

Source Edit

  1. proc add[T](L: var DoublyLinkedList[T]; value: T)

Appends (adds to the end) a value to L. Efficiency: O(1).

See also:

Example:

  1. var a = initDoublyLinkedList[int]()
  2. a.add(9)
  3. a.add(8)
  4. assert a.contains(9)

Source Edit

  1. 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:

  1. var a = initDoublyLinkedRing[int]()
  2. let n = newDoublyLinkedNode[int](9)
  3. a.add(n)
  4. assert a.contains(9)

Source Edit

  1. proc add[T](L: var DoublyLinkedRing[T]; value: T)

Appends (adds to the end) a value to L. Efficiency: O(1).

See also:

Example:

  1. var a = initDoublyLinkedRing[int]()
  2. a.add(9)
  3. a.add(8)
  4. assert a.contains(9)

Source Edit

  1. 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:

  1. var a = initSinglyLinkedList[int]()
  2. let n = newSinglyLinkedNode[int](9)
  3. a.add(n)
  4. assert a.contains(9)

Source Edit

  1. 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:

  1. var a = initSinglyLinkedList[int]()
  2. a.add(9)
  3. a.add(8)
  4. assert a.contains(9)

Source Edit

  1. 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:

  1. var a = initSinglyLinkedRing[int]()
  2. let n = newSinglyLinkedNode[int](9)
  3. a.add(n)
  4. assert a.contains(9)

Source Edit

  1. proc add[T](L: var SinglyLinkedRing[T]; value: T)

Appends (adds to the end) a value to L. Efficiency: O(1).

See also:

Example:

  1. var a = initSinglyLinkedRing[int]()
  2. a.add(9)
  3. a.add(8)
  4. assert a.contains(9)

Source Edit

  1. 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:

  1. import std/[sequtils, enumerate, sugar]
  2. var
  3. a = [1, 2, 3].toDoublyLinkedList
  4. b = [4, 5].toDoublyLinkedList
  5. c = [0, 1].toDoublyLinkedList
  6. a.addMoved(b)
  7. assert a.toSeq == [1, 2, 3, 4, 5]
  8. assert b.toSeq == []
  9. c.addMoved(c)
  10. let s = collect:
  11. for i, ci in enumerate(c):
  12. if i == 6: break
  13. ci
  14. assert s == [0, 1, 0, 1, 0, 1]

Source Edit

  1. 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:

  1. import std/[sequtils, enumerate, sugar]
  2. var
  3. a = [1, 2, 3].toSinglyLinkedList
  4. b = [4, 5].toSinglyLinkedList
  5. c = [0, 1].toSinglyLinkedList
  6. a.addMoved(b)
  7. assert a.toSeq == [1, 2, 3, 4, 5]
  8. assert b.toSeq == []
  9. c.addMoved(c)
  10. let s = collect:
  11. for i, ci in enumerate(c):
  12. if i == 6: break
  13. ci
  14. assert s == [0, 1, 0, 1, 0, 1]

Source Edit

  1. proc append[T](a: var (DoublyLinkedList[T] | DoublyLinkedRing[T]);
  2. b: DoublyLinkedList[T] | DoublyLinkedNode[T] | T)

Alias for a.add(b).

See also:

Source Edit

  1. proc append[T](a: var (SinglyLinkedList[T] | SinglyLinkedRing[T]);
  2. b: SinglyLinkedList[T] | SinglyLinkedNode[T] | T)

Alias for a.add(b).

See also:

Source Edit

  1. proc appendMoved[T: SomeLinkedList](a, b: var T)

Alias for a.addMoved(b).

See also:

Source Edit

  1. 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:

  1. let a = [9, 8].toSinglyLinkedList
  2. assert a.contains(9)
  3. assert 8 in a
  4. assert(not a.contains(1))
  5. assert 2 notin a

Source Edit

  1. func copy[T](a: DoublyLinkedList[T]): DoublyLinkedList[T]

Creates a shallow copy of a.

Example:

  1. from std/sequtils import toSeq
  2. type Foo = ref object
  3. x: int
  4. var
  5. f = Foo(x: 1)
  6. a = [f].toDoublyLinkedList
  7. let b = a.copy
  8. a.add([f].toDoublyLinkedList)
  9. assert a.toSeq == [f, f]
  10. assert b.toSeq == [f] # b isn't modified...
  11. f.x = 42
  12. assert a.head.value.x == 42
  13. assert b.head.value.x == 42 # ... but the elements are not deep copied
  14. let c = [1, 2, 3].toDoublyLinkedList
  15. assert $c == $c.copy

Source Edit

  1. func copy[T](a: SinglyLinkedList[T]): SinglyLinkedList[T]

Creates a shallow copy of a.

Example:

  1. from std/sequtils import toSeq
  2. type Foo = ref object
  3. x: int
  4. var
  5. f = Foo(x: 1)
  6. a = [f].toSinglyLinkedList
  7. let b = a.copy
  8. a.add([f].toSinglyLinkedList)
  9. assert a.toSeq == [f, f]
  10. assert b.toSeq == [f] # b isn't modified...
  11. f.x = 42
  12. assert a.head.value.x == 42
  13. assert b.head.value.x == 42 # ... but the elements are not deep copied
  14. let c = [1, 2, 3].toSinglyLinkedList
  15. assert $c == $c.copy

Source Edit

  1. proc find[T](L: SomeLinkedCollection[T]; value: T): SomeLinkedNode[T]

Searches in the list for a value. Returns nil if the value does not exist.

See also:

Example:

  1. let a = [9, 8].toSinglyLinkedList
  2. assert a.find(9).value == 9
  3. assert a.find(1) == nil

Source Edit

  1. proc initDoublyLinkedList[T](): DoublyLinkedList[T]

Creates a new doubly linked list that is empty.

Doubly linked lists are initialized by default, so it is not necessary to call this function explicitly.

Example:

  1. let a = initDoublyLinkedList[int]()

Source Edit

  1. proc initDoublyLinkedRing[T](): DoublyLinkedRing[T]

Creates a new doubly linked ring that is empty.

Doubly linked rings are initialized by default, so it is not necessary to call this function explicitly.

Example:

  1. let a = initDoublyLinkedRing[int]()

Source Edit

  1. proc initSinglyLinkedList[T](): SinglyLinkedList[T]

Creates a new singly linked list that is empty.

Singly linked lists are initialized by default, so it is not necessary to call this function explicitly.

Example:

  1. let a = initSinglyLinkedList[int]()

Source Edit

  1. proc initSinglyLinkedRing[T](): SinglyLinkedRing[T]

Creates a new singly linked ring that is empty.

Singly linked rings are initialized by default, so it is not necessary to call this function explicitly.

Example:

  1. let a = initSinglyLinkedRing[int]()

Source Edit

  1. proc newDoublyLinkedNode[T](value: T): DoublyLinkedNode[T]

Creates a new doubly linked node with the given value.

Example:

  1. let n = newDoublyLinkedNode[int](5)
  2. assert n.value == 5

Source Edit

  1. proc newSinglyLinkedNode[T](value: T): SinglyLinkedNode[T]

Creates a new singly linked node with the given value.

Example:

  1. let n = newSinglyLinkedNode[int](5)
  2. assert n.value == 5

Source Edit

  1. proc prepend[T: SomeLinkedList](a: var T; b: T)

Prepends a shallow copy of b to the beginning of a.

See also:

Example:

  1. from std/sequtils import toSeq
  2. var a = [4, 5].toSinglyLinkedList
  3. let b = [1, 2, 3].toSinglyLinkedList
  4. a.prepend(b)
  5. assert a.toSeq == [1, 2, 3, 4, 5]
  6. assert b.toSeq == [1, 2, 3]
  7. a.prepend(a)
  8. assert a.toSeq == [1, 2, 3, 4, 5, 1, 2, 3, 4, 5]

Source Edit

  1. 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:

  1. var a = initDoublyLinkedList[int]()
  2. let n = newDoublyLinkedNode[int](9)
  3. a.prepend(n)
  4. assert a.contains(9)

Source Edit

  1. proc prepend[T](L: var DoublyLinkedList[T]; value: T)

Prepends (adds to the beginning) a value to L. Efficiency: O(1).

See also:

Example:

  1. var a = initDoublyLinkedList[int]()
  2. a.prepend(9)
  3. a.prepend(8)
  4. assert a.contains(9)

Source Edit

  1. 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:

  1. var a = initDoublyLinkedRing[int]()
  2. let n = newDoublyLinkedNode[int](9)
  3. a.prepend(n)
  4. assert a.contains(9)

Source Edit

  1. proc prepend[T](L: var DoublyLinkedRing[T]; value: T)

Prepends (adds to the beginning) a value to L. Efficiency: O(1).

See also:

Example:

  1. var a = initDoublyLinkedRing[int]()
  2. a.prepend(9)
  3. a.prepend(8)
  4. assert a.contains(9)

Source Edit

  1. 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:

  1. var a = initSinglyLinkedList[int]()
  2. let n = newSinglyLinkedNode[int](9)
  3. a.prepend(n)
  4. assert a.contains(9)

Source Edit

  1. 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:

  1. var a = initSinglyLinkedList[int]()
  2. a.prepend(9)
  3. a.prepend(8)
  4. assert a.contains(9)

Source Edit

  1. 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:

  1. var a = initSinglyLinkedRing[int]()
  2. let n = newSinglyLinkedNode[int](9)
  3. a.prepend(n)
  4. assert a.contains(9)

Source Edit

  1. proc prepend[T](L: var SinglyLinkedRing[T]; value: T)

Prepends (adds to the beginning) a value to L. Efficiency: O(1).

See also:

Example:

  1. var a = initSinglyLinkedRing[int]()
  2. a.prepend(9)
  3. a.prepend(8)
  4. assert a.contains(9)

Source Edit

  1. 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:

  1. import std/[sequtils, enumerate, sugar]
  2. var
  3. a = [4, 5].toSinglyLinkedList
  4. b = [1, 2, 3].toSinglyLinkedList
  5. c = [0, 1].toSinglyLinkedList
  6. a.prependMoved(b)
  7. assert a.toSeq == [1, 2, 3, 4, 5]
  8. assert b.toSeq == []
  9. c.prependMoved(c)
  10. let s = collect:
  11. for i, ci in enumerate(c):
  12. if i == 6: break
  13. ci
  14. assert s == [0, 1, 0, 1, 0, 1]

Source Edit

  1. proc remove[T](L: var DoublyLinkedList[T]; n: DoublyLinkedNode[T])

Removes a node 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:

  1. import std/[sequtils, enumerate, sugar]
  2. var a = [0, 1, 2].toSinglyLinkedList
  3. let n = a.head.next
  4. assert n.value == 1
  5. a.remove(n)
  6. assert a.toSeq == [0, 2]
  7. a.remove(n)
  8. assert a.toSeq == [0, 2]
  9. a.addMoved(a) # cycle: [0, 2, 0, 2, ...]
  10. a.remove(a.head)
  11. let s = collect:
  12. for i, ai in enumerate(a):
  13. if i == 4: break
  14. ai
  15. assert s == [2, 2, 2, 2]

Source Edit

  1. proc remove[T](L: var DoublyLinkedRing[T]; n: DoublyLinkedNode[T])

Removes 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:

  1. var a = initDoublyLinkedRing[int]()
  2. let n = newDoublyLinkedNode[int](5)
  3. a.add(n)
  4. assert 5 in a
  5. a.remove(n)
  6. assert 5 notin a

Source Edit

  1. proc remove[T](L: var SinglyLinkedList[T]; n: SinglyLinkedNode[T]): bool {.
  2. discardable.}

Removes a node 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:

  1. import std/[sequtils, enumerate, sugar]
  2. var a = [0, 1, 2].toSinglyLinkedList
  3. let n = a.head.next
  4. assert n.value == 1
  5. assert a.remove(n) == true
  6. assert a.toSeq == [0, 2]
  7. assert a.remove(n) == false
  8. assert a.toSeq == [0, 2]
  9. a.addMoved(a) # cycle: [0, 2, 0, 2, ...]
  10. a.remove(a.head)
  11. let s = collect:
  12. for i, ai in enumerate(a):
  13. if i == 4: break
  14. ai
  15. assert s == [2, 2, 2, 2]

Source Edit

  1. func toDoublyLinkedList[T](elems: openArray[T]): DoublyLinkedList[T]

Creates a new DoublyLinkedList from the members of elems.

Example:

  1. from std/sequtils import toSeq
  2. let a = [1, 2, 3, 4, 5].toDoublyLinkedList
  3. assert a.toSeq == [1, 2, 3, 4, 5]

Source Edit

  1. func toSinglyLinkedList[T](elems: openArray[T]): SinglyLinkedList[T]

Creates a new SinglyLinkedList from the members of elems.

Example:

  1. from std/sequtils import toSeq
  2. let a = [1, 2, 3, 4, 5].toSinglyLinkedList
  3. assert a.toSeq == [1, 2, 3, 4, 5]

Source Edit

Iterators

  1. iterator items[T](L: SomeLinkedList[T]): T

Yields every value of L.

See also:

Example:

  1. from std/sugar import collect
  2. from std/sequtils import toSeq
  3. let a = collect(initSinglyLinkedList):
  4. for i in 1..3: 10 * i
  5. assert toSeq(items(a)) == toSeq(a)
  6. assert toSeq(a) == @[10, 20, 30]

Source Edit

  1. iterator items[T](L: SomeLinkedRing[T]): T

Yields every value of L.

See also:

Example:

  1. from std/sugar import collect
  2. from std/sequtils import toSeq
  3. let a = collect(initSinglyLinkedRing):
  4. for i in 1..3: 10 * i
  5. assert toSeq(items(a)) == toSeq(a)
  6. assert toSeq(a) == @[10, 20, 30]

Source Edit

  1. iterator mitems[T](L: var SomeLinkedList[T]): var T

Yields every value of L so that you can modify it.

See also:

Example:

  1. var a = initSinglyLinkedList[int]()
  2. for i in 1..5:
  3. a.add(10 * i)
  4. assert $a == "[10, 20, 30, 40, 50]"
  5. for x in mitems(a):
  6. x = 5 * x - 1
  7. assert $a == "[49, 99, 149, 199, 249]"

Source Edit

  1. iterator mitems[T](L: var SomeLinkedRing[T]): var T

Yields every value of L so that you can modify it.

See also:

Example:

  1. var a = initSinglyLinkedRing[int]()
  2. for i in 1..5:
  3. a.add(10 * i)
  4. assert $a == "[10, 20, 30, 40, 50]"
  5. for x in mitems(a):
  6. x = 5 * x - 1
  7. assert $a == "[49, 99, 149, 199, 249]"

Source Edit

  1. 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:

  1. var a = initDoublyLinkedList[int]()
  2. for i in 1..5:
  3. a.add(10 * i)
  4. assert $a == "[10, 20, 30, 40, 50]"
  5. for x in nodes(a):
  6. if x.value == 30:
  7. a.remove(x)
  8. else:
  9. x.value = 5 * x.value - 1
  10. assert $a == "[49, 99, 199, 249]"

Source Edit

  1. 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:

  1. var a = initDoublyLinkedRing[int]()
  2. for i in 1..5:
  3. a.add(10 * i)
  4. assert $a == "[10, 20, 30, 40, 50]"
  5. for x in nodes(a):
  6. if x.value == 30:
  7. a.remove(x)
  8. else:
  9. x.value = 5 * x.value - 1
  10. assert $a == "[49, 99, 199, 249]"

Source Edit