Documentation
¶
Overview ¶
Package linked provides a doubly-linked list implementation with support for generics.
Index ¶
- Constants
- func NoopSeq[T any](_ func(T) bool)
- type Edge
- type Iterator
- func (it *Iterator[T]) All() iter.Seq[*Node[T]]
- func (it *Iterator[T]) Count() (n int)
- func (it *Iterator[T]) Gather() (values []T)
- func (it *Iterator[T]) Init(node *Node[T], backward ...bool)
- func (it *Iterator[T]) Into(dst []T) (n int)
- func (it *Iterator[T]) IsBackward() bool
- func (it *Iterator[T]) Next() bool
- func (it *Iterator[T]) Version() uint
- type List
- func (l *List[T]) All() iter.Seq[T]
- func (l *List[T]) Back() *Node[T]
- func (l *List[T]) Backward() iter.Seq[T]
- func (l *List[T]) Clear() *List[T]
- func (l *List[T]) Copy() *List[T]
- func (l *List[T]) Edge(edge Edge) *Node[T]
- func (l *List[T]) ForEach(fn func(v T), backward ...bool)
- func (l *List[T]) Front() *Node[T]
- func (l *List[T]) Insert(v T, target *Node[T], edge Edge) *Node[T]
- func (l *List[T]) InsertAfter(v T, target *Node[T]) *Node[T]
- func (l *List[T]) InsertBefore(v T, target *Node[T]) *Node[T]
- func (l *List[T]) InsertMany(values []T, target *Node[T], edge Edge, backward ...bool) (*Node[T], *Node[T])
- func (l *List[T]) InsertManyAfter(values []T, target *Node[T], backward ...bool) (*Node[T], *Node[T])
- func (l *List[T]) InsertManyBefore(values []T, target *Node[T], backward ...bool) (*Node[T], *Node[T])
- func (l *List[T]) IsMember(node *Node[T]) bool
- func (l *List[T]) Iter(backward ...bool) (it Iterator[T])
- func (l *List[T]) Len() int
- func (l *List[T]) Move(node, target *Node[T], edge Edge) *Node[T]
- func (l *List[T]) MoveAfter(node, target *Node[T]) *Node[T]
- func (l *List[T]) MoveBefore(node, target *Node[T]) *Node[T]
- func (l *List[T]) MoveToBack(node *Node[T]) *Node[T]
- func (l *List[T]) MoveToEdge(node *Node[T], edge Edge) *Node[T]
- func (l *List[T]) MoveToFront(node *Node[T]) *Node[T]
- func (l *List[T]) Pop(edge Edge) (node *Node[T])
- func (l *List[T]) PopBack() (node *Node[T])
- func (l *List[T]) PopFront() (node *Node[T])
- func (l *List[T]) Push(v T, edge Edge) *Node[T]
- func (l *List[T]) PushBack(v T) *Node[T]
- func (l *List[T]) PushFront(v T) *Node[T]
- func (l *List[T]) Remove(node *Node[T]) T
- func (l *List[T]) Rotate(steps int, edge Edge) *List[T]
- func (l *List[T]) RotateLeft(steps int) *List[T]
- func (l *List[T]) RotateRight(steps int) *List[T]
- func (l *List[T]) Take(inherit, target *Node[T], edge Edge) *Node[T]
- func (l *List[T]) TakeAfter(inherit, target *Node[T]) *Node[T]
- func (l *List[T]) TakeBefore(inherit, target *Node[T]) *Node[T]
- func (l *List[T]) Version() uint
- type Node
- func (n *Node[T]) All() iter.Seq[T]
- func (n *Node[T]) Backward() iter.Seq[T]
- func (n *Node[T]) IsBack() bool
- func (n *Node[T]) IsEdge(edge Edge) bool
- func (n *Node[T]) IsFront() bool
- func (n *Node[T]) IsMember(of *List[T]) bool
- func (n *Node[T]) IsOrphan() bool
- func (n *Node[T]) Iter(backward ...bool) (it Iterator[T])
- func (n *Node[T]) Move(target *Node[T], edge Edge) *Node[T]
- func (n *Node[T]) MoveAfter(target *Node[T]) *Node[T]
- func (n *Node[T]) MoveBefore(target *Node[T]) *Node[T]
- func (n *Node[T]) MoveToBack() *Node[T]
- func (n *Node[T]) MoveToEdge(edge Edge) *Node[T]
- func (n *Node[T]) MoveToFront() *Node[T]
- func (n *Node[T]) Next() *Node[T]
- func (n *Node[T]) OK() bool
- func (n *Node[T]) Peer(edge Edge) *Node[T]
- func (n *Node[T]) Pop() *Node[T]
- func (n *Node[T]) Prev() *Node[T]
- func (n *Node[T]) Remove() T
Examples ¶
Constants ¶
const ( Left = Edge(iota) // Left edge of a [List] or [Node]. Right // Right edge of a [List] or [Node]. )
const ( Before = Left Prev = Left Front = Left )
Aliases for Left (for the pedantic amongst us).
const ( After = Right Next = Right Back = Right )
Aliases for Right (for the pedantic amongst us).
Variables ¶
This section is empty.
Functions ¶
Types ¶
type Edge ¶
type Edge int
Edge is a simple enumeration type which is used to refer to a Node relative to another Node or List. It has only two concrete values: Left and Right.
func (Edge) List ¶
List returns "Front" or "Back" to describe which end of a List is referred to by this Edge.
func (Edge) Opposite ¶
Opposite returns the opposite value of the receiver or panics if the receiver is not a valid Edge.
func (Edge) String ¶
String implements fmt.Stringer for Edge and returns the canonical name of the receiver ("Left" or "Right") or, if invalid, a string in the form of
"(%!BadEdge(%d))"
type Iterator ¶
type Iterator[T any] struct { // Node is the current position of the iterator. When nil, iteration has // completed. For performance reasons, the field is public, rather than // wrapped as a method. // // It is discouraged (but not always incorrect) to assign directly to this // field once iteration has started. Node *Node[T] // Pos is a pseudo-index which tracks the iteration position relative to // the origin [Node]. For performance reasons, the field is public, rather // than wrapped as a method. // // It is discouraged to assign directly to this field. Pos int // contains filtered or unexported fields }
Iterator is a simple object-based iterator that provides leftward and rightward traversal of the Node objects found in a List.
Note: this object does *NOT* track any of the [Node]s that it has visited, and is therefore sensitive to any mutations of the associated List.
func (*Iterator[T]) Count ¶
Count returns the number of times this Iterator has been successfully advanced.
func (*Iterator[T]) Gather ¶
func (it *Iterator[T]) Gather() (values []T)
Gather expends the remainder of this Iterator, placing the value of each remaining Node into a slice. The slice is nil if the iterator is spent.
func (*Iterator[T]) Init ¶
Init initializes the Iterator, beginning at the given Node. Iteration occurs from Left to Right unless backward is true.
func (*Iterator[T]) Into ¶
Into advances the iterator up to len(dst) times, placing the value of each yielded Node into the given slice at the next position. Returns the number of values placed into the slice.
func (*Iterator[T]) IsBackward ¶
IsBackward indicates if this Iterator is iterating in reverse order.
func (*Iterator[T]) Next ¶
Next advances the iterator. It returns true if the Node on the Iterator can be safely read or false if it will be nil.
func (*Iterator[T]) Version ¶
Version returns the value of List.Version at the time Iterator.Init was called, useful for detecting if the List has mutated (though it won't tell you where or how).
type List ¶
type List[T any] struct { // contains filtered or unexported fields }
List implements a doubly-linked list. The zero value of a List is ready to use. Must not be modified concurrently.
func New ¶
New creates a new doubly-linked List, initially populated with the values of the given slice (which may be nil). If backward is true, they are placed into the List in reverse order.
func (*List[T]) Copy ¶
Copy creates an exact copy of this List and Node objects. The [Node]s of the new List will be allocated in contiguous memory space, if possible (OS and runtime dependent).
func (*List[T]) Edge ¶
Edge returns the Node on the Left or Right edge of this List, or panics if edge is invalid.
func (*List[T]) ForEach ¶
ForEach iterates over the values of this List and executes the given function for each value. If backward is true, it iterates in reverse order.
Example ¶
list := linked.New([]string{"A", "B", "C", "D"})
list.ForEach(func(v string) { fmt.Println(v) })
list.ForEach(func(v string) { fmt.Println(v) }, true) // reverse order
Output: A B C D D C B A
func (*List[T]) Insert ¶
Insert places a new value into this List on the Left or Right edge of the target Node. If the target is nil, it implies the Node on the specified Edge of this List (behaving as List.Push does).
If target does not belong to this List, this method is a no-op and returns nil to indicate failure.
The edge must be valid, otherwise this method panics.
On success returns the Node of the value that was just inserted.
func (*List[T]) InsertAfter ¶
InsertAfter inserts a new value After the target Node using List.Insert.
func (*List[T]) InsertBefore ¶
InsertBefore inserts a new value Before the target Node using List.Insert.
func (*List[T]) InsertMany ¶
func (l *List[T]) InsertMany(values []T, target *Node[T], edge Edge, backward ...bool) (*Node[T], *Node[T])
InsertMany efficiently inserts an entire slice of values into this List Before or After the target Node.
If backward is true, the values are inserted in reverse order.
If the target Node is nil, it implies the Node on the specified Edge of this List. Otherwise, if the target is not a member of this List, this method is a no-op and returns two nil pointers to indicate failure.
The edge must be valid, otherwise this method panics.
On success, returns the first and last [Node]s that were inserted.
func (*List[T]) InsertManyAfter ¶
func (l *List[T]) InsertManyAfter(values []T, target *Node[T], backward ...bool) (*Node[T], *Node[T])
InsertManyAfter inserts the slice of values After the target Node using List.InsertMany.
Example ¶
list := linked.New([]string{"G", "A"})
target := list.Front()
oldPeer := target.Next()
left, right := list.InsertManyAfter(
[]string{"B", "C", "D", "E", "F"},
target,
true, // reverse the order when inserting
)
fmt.Printf("inserted %q after %q\n", left.Value, target.Value)
fmt.Printf("inserted %q before %q\n", right.Value, oldPeer.Value)
list.ForEach(func(v string) { fmt.Println(v) })
Output: inserted "F" after "G" inserted "B" before "A" G F E D C B A
func (*List[T]) InsertManyBefore ¶
func (l *List[T]) InsertManyBefore(values []T, target *Node[T], backward ...bool) (*Node[T], *Node[T])
InsertManyBefore inserts the slice of values Before the target Node using List.InsertMany.
Example ¶
list := linked.New([]string{"A", "G"})
target := list.Back()
oldPeer := target.Prev()
left, right := list.InsertManyBefore([]string{"B", "C", "D", "E", "F"}, target)
fmt.Printf("inserted %q after %q\n", left.Value, oldPeer.Value)
fmt.Printf("inserted %q before %q\n", right.Value, target.Value)
list.ForEach(func(v string) { fmt.Println(v) })
Output: inserted "B" after "A" inserted "F" before "G" A B C D E F G
func (*List[T]) IsMember ¶
IsMember indicates if the given Node belongs to this List. The Node must not be nil. Always returns false if this List is nil.
func (*List[T]) Iter ¶
Iter returns an Iterator which traverses the [Node]s of this List from Front to Back, or from Back to Front if backward is true.
Example ¶
list := linked.New([]string{"A", "B", "C", "D", "E", "F", "G"})
for it := list.Iter(); it.Next(); {
fmt.Printf("%q // pos=%d, count=%d\n", it.Node.Value, it.Pos, it.Count())
}
Output: "A" // pos=0, count=1 "B" // pos=1, count=2 "C" // pos=2, count=3 "D" // pos=3, count=4 "E" // pos=4, count=5 "F" // pos=5, count=6 "G" // pos=6, count=7
func (*List[T]) Move ¶
Move moves the given Node so that it occurs Before or After the target Node. If the target is nil, it implies the Node on the specified Edge of this List. The node which is being moved must not be nil. The edge must also be valid, otherwise this method panics.
If either Node does not belong to this List, this method is a no-op and returns nil to indicate failure.
On success, returns the (same) Node that was moved.
func (*List[T]) MoveAfter ¶
MoveAfter moves the given Node to the Right of the target Node using List.Move.
func (*List[T]) MoveBefore ¶
MoveBefore moves the given Node to the Left of the target Node using List.Move.
func (*List[T]) MoveToBack ¶
MoveToBack moves the given Node to the Back edge of this List in the same manner as described by List.MoveToEdge.
func (*List[T]) MoveToEdge ¶
MoveToEdge efficiently moves the given Node to the Front or Back Edge of this List. The node must not be nil and the edge must be valid, otherwise this method panics.
If the Node doesn't belong to this List, this method is a no-op and returns nil to indicate failure.
On success, returns the same Node. See also: List.MoveToFront and List.MoveToBack, which are slightly more efficient.
func (*List[T]) MoveToFront ¶
MoveToFront moves the given Node to the Front edge of this List in the same manner as described by List.MoveToEdge.
func (*List[T]) Pop ¶
Pop removes and returns the node from the Front or Back of this List, or returns nil if empty. The edge must be valid, otherwise this method panics.
func (*List[T]) PopBack ¶
PopBack removes and returns Back Node via List.Pop.
Example ¶
list := linked.New([]int{1, 2, 3, 4, 5})
for list.Len() > 0 {
fmt.Printf("%d\n", list.PopBack().Value)
}
Output: 5 4 3 2 1
func (*List[T]) PopFront ¶
PopFront removes and returns Front Node via List.Pop.
Example ¶
list := linked.New([]int{1, 2, 3, 4, 5})
for list.Len() > 0 {
fmt.Printf("%d\n", list.PopFront().Value)
}
Output: 1 2 3 4 5
func (*List[T]) Push ¶
Push inserts a new value at the Front or Back of this List and returns the Node that stores the value. The edge must be valid, otherwise this method panics.
func (*List[T]) PushBack ¶
PushBack pushes a new value to the Back of this List via List.Push.
Example ¶
var list linked.List[int]
for v := range 5 {
list.PushBack(v)
}
list.ForEach(func(v int) { fmt.Printf("%d\n", v) })
Output: 0 1 2 3 4
func (*List[T]) PushFront ¶
PushFront pushes a new value to the Front of this List via List.Push.
Example ¶
var list linked.List[int]
for v := range 5 {
list.PushFront(v)
}
list.ForEach(func(v int) { fmt.Printf("%d\n", v) })
Output: 4 3 2 1 0
func (*List[T]) Remove ¶
Remove deletes the given Node from this List. The Node must not be nil. Does nothing if the Node does not belong to this List. Always returns the value stored on the Node.
func (*List[T]) Rotate ¶
Rotate rotates the [Node]s of this List by the specified number of steps to the Left or Right, as determined by Edge. The edge must be valid. This method is a no-op if steps is less than 1 or a multiple of List.Len. The number of steps can be greater than the list length, which reduces via:
steps %= list.Len()
Always returns the receiver (this List).
func (*List[T]) RotateLeft ¶
RotateLeft rotates this List to the Left by the specified number of steps using List.Rotate.
func (*List[T]) RotateRight ¶
RotateRight rotates this List to the Right by the specified number of steps using List.Rotate.
func (*List[T]) Take ¶
Take inherits a Node that does not belong to this List, placing it into the List Before or After the target Node. If the target is nil, it implies the Node on the specified Edge of this List.
If the Node to inherit already belongs to this List, or the target Node *does not* belong to this List, this method is a no-op and returns nil to indicate failure.
The Node to inherit must not be nil and the edge must be valid, otherwise this method panics.
Returns the inherited Node on success.
func (*List[T]) TakeAfter ¶
TakeAfter inherits a Node, inserting it After the target Node using List.Take.
type Node ¶
type Node[T any] struct { Value T // contains filtered or unexported fields }
Node represents an element of a List.
func (*Node[T]) All ¶
All yields the value stored in this Node and the value of each Node which occurs After it (i.e. iterates from Front to Back).
func (*Node[T]) Backward ¶
Backward yields the value stored in this Node and the value of each Node which occurs Before it (i.e. iterates from Back to Front).
func (*Node[T]) IsBack ¶
IsBack indicates if this Node is at the Back of its List using Node.IsEdge.
func (*Node[T]) IsEdge ¶
IsEdge indicates if this Node is at the given Edge of its List. The edge must be valid, otherwise this method panics.
func (*Node[T]) IsFront ¶
IsFront indicates if this Node is at the Front of its List using Node.IsEdge.
func (*Node[T]) IsMember ¶
IsMember indicates if this Node is a member of the given List. If the given List is nil, indicates if this Node is orphaned.
func (*Node[T]) Iter ¶
Iter returns an Iterator which begins at (and is inclusive of) this Node. Consumes up to one optional argument indicating if reverse iteration is desired. Calling this method against a nil receiver never panics.
func (*Node[T]) Move ¶
Move moves this Node to the Left or Right Edge of the target Node using List.Move. On success, returns the receiver, otherwise nil.
func (*Node[T]) MoveAfter ¶
MoveAfter moves this Node to the Right Edge of the target Node using Node.Move.
func (*Node[T]) MoveBefore ¶
MoveBefore moves this Node to the Left Edge of the target Node using Node.Move.
func (*Node[T]) MoveToBack ¶
MoveToBack moves this Node to the Back of its List using Node.MoveToEdge.
func (*Node[T]) MoveToEdge ¶
MoveToEdge moves this Node to the Front or Back edge of its List. Returns the receiver if this Node belongs to any List, otherwise nil. Edge must be Left, Right, or an alias thereof.
func (*Node[T]) MoveToFront ¶
MoveToFront moves this Node to the Front of its List using Node.MoveToEdge.
func (*Node[T]) OK ¶
OK returns true if the receiver is non-nil without causing a panic. This is intended for convenience as a shortcut for determining if a List operation was successful.
func (*Node[T]) Peer ¶
Peer returns the Node to the Left or Right edge of this Node, if any. Panics if edge is invalid.
func (*Node[T]) Pop ¶
Pop removes this Node from the List to which it belongs, if any. Always returns itself.