github.com/Nigel2392/go-datastructures@v1.1.5/linkedlist/singly.go (about) 1 package linkedlist 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "strings" 7 ) 8 9 // A singly linked list. 10 // 11 // This is a generic type, so you can use it with any type. 12 // 13 // For example, Singly[int] is a linked list of integers. 14 // 15 // If using an uncomparable type, the Remove(value) method will not work. 16 // 17 // You can only use RemoveIndex(index). 18 type Singly[T any] struct { 19 head *Node[T] 20 len int 21 } 22 23 // Returns the length of the list. 24 func (l *Singly[T]) Len() int { 25 return l.len 26 } 27 28 // Returns the list as a string. 29 func (l *Singly[T]) String() string { 30 var b strings.Builder 31 b.WriteString("[") 32 for n := l.head; n != nil; n = n.next { 33 fmt.Fprintf(&b, "%v", n.value) 34 if n.next != nil { 35 b.WriteString(", ") 36 } 37 } 38 b.WriteString("]") 39 return b.String() 40 } 41 42 // Returns the head of the list. 43 func (l *Singly[T]) Head() *Node[T] { 44 return l.head 45 } 46 47 // Prepend a value to the beginning of the list. 48 func (l *Singly[T]) Prepend(v T) { 49 var n = &Node[T]{value: v} 50 l.prepend(n) 51 } 52 53 // Shift a value from the beginning of the list. 54 // 55 // Returns the value that was shifted. 56 func (l *Singly[T]) Shift() T { 57 if l.len == 0 { 58 panic("cannot shift from an empty list") 59 } 60 var v = l.head.value 61 l.RemoveIndex(0) 62 return v 63 } 64 65 // Reset the list. 66 func (l *Singly[T]) Reset() { 67 l.head = nil 68 l.len = 0 69 } 70 71 // Remove a value from the list. 72 // 73 // This function will panic with uncomparable types. 74 // 75 // Use RemoveIndex(index) instead. 76 func (l *Singly[T]) Remove(v T) bool { 77 if l.len == 0 { 78 return false 79 } 80 var i = 0 81 for n := l.head; n != nil; n = n.next { 82 if any(n.value) == any(v) { // panic on comparison of uncomparable types. 83 l.remove(i, n) 84 return true 85 } 86 i++ 87 } 88 return false 89 } 90 91 // Remove a value from the list at a given index. 92 func (l *Singly[T]) RemoveIndex(i int) bool { 93 if i < 0 || i >= l.len { 94 return false 95 } 96 97 if i == 0 { 98 l.remove(i, l.head) 99 return true 100 } 101 102 var n *Node[T] 103 n = l.head 104 for j := 0; j < i; j++ { 105 n = n.next 106 } 107 if n != nil { 108 l.remove(i, n) 109 return true 110 } 111 return false 112 } 113 114 // Remove a value from the list if the predicate returns true. 115 // 116 // Returns the number of values removed. 117 func (l *Singly[T]) RemoveIf(predicate func(T) bool) int { 118 var removed = 0 119 var i = 0 120 for n := l.head; n != nil; n = n.next { 121 if predicate(n.value) { 122 l.remove(i, n) 123 removed++ 124 } 125 i++ 126 } 127 return removed 128 } 129 130 // Returns the list as a slice. 131 func (l *Singly[T]) ToSlice() []T { 132 if l.len == 0 { 133 return nil 134 } 135 var slice = make([]T, l.len) 136 var i = 0 137 for n := l.head; n != nil; n = n.next { 138 slice[i] = n.value 139 i++ 140 } 141 return slice 142 } 143 144 // MarshalJSON implements the json.Marshaler interface. 145 func (l *Singly[T]) MarshalJSON() ([]byte, error) { 146 return json.Marshal(l.ToSlice()) 147 } 148 149 // UnmarshalJSON implements the json.Unmarshaler interface. 150 func (l *Singly[T]) UnmarshalJSON(data []byte) error { 151 var slice []T 152 if err := json.Unmarshal(data, &slice); err != nil { 153 return err 154 } 155 for _, v := range slice { 156 l.Prepend(v) 157 } 158 return nil 159 } 160 161 func (l *Singly[T]) prepend(n *Node[T]) { 162 if l.head == nil { 163 l.head = n 164 } else { 165 var oldHead = l.head 166 l.head = n 167 l.head.next = oldHead 168 } 169 l.len++ 170 } 171 172 // remove removes a node from the list. 173 func (l *Singly[T]) remove(i int, n *Node[T]) { 174 if i == 0 { 175 l.head = n.next 176 } else { 177 if n.next != nil { 178 *n = *n.next 179 } 180 } 181 l.len-- 182 183 }