github.com/songzhibin97/go-baseutils@v0.0.2-0.20240302024150-487d8ce9c082/structure/lists/singlylinkedlist/singlylinkedlist.go (about) 1 // Package singlylinkedlist implements the singly-linked list. 2 // 3 // Structure is not thread safe. 4 // 5 // Reference: https://en.wikipedia.org/wiki/List_%28abstract_data_type%29 6 package singlylinkedlist 7 8 import ( 9 "encoding/json" 10 "fmt" 11 "github.com/songzhibin97/go-baseutils/base/bcomparator" 12 "github.com/songzhibin97/go-baseutils/structure/lists" 13 "reflect" 14 "strings" 15 ) 16 17 // Assert List implementation 18 var _ lists.List[any] = (*List[any])(nil) 19 20 func NewSafe[E any](values ...E) *ListSafe[E] { 21 return &ListSafe[E]{ 22 unsafe: New(values...), 23 } 24 } 25 26 // List holds the elements, where each element points to the next element 27 type List[E any] struct { 28 first *element[E] 29 last *element[E] 30 size int 31 zero E 32 } 33 34 type element[E any] struct { 35 value E 36 next *element[E] 37 } 38 39 // New instantiates a new list and adds the passed values, if any, to the list 40 func New[E any](values ...E) *List[E] { 41 list := &List[E]{} 42 if len(values) > 0 { 43 list.Add(values...) 44 } 45 return list 46 } 47 48 // Add appends a value (one or more) at the end of the list (same as Append()) 49 func (list *List[E]) Add(values ...E) { 50 for _, value := range values { 51 newElement := &element[E]{value: value} 52 if list.size == 0 { 53 list.first = newElement 54 list.last = newElement 55 } else { 56 list.last.next = newElement 57 list.last = newElement 58 } 59 list.size++ 60 } 61 } 62 63 // Append appends a value (one or more) at the end of the list (same as Add()) 64 func (list *List[E]) Append(values ...E) { 65 list.Add(values...) 66 } 67 68 // Prepend prepends a values (or more) 69 func (list *List[E]) Prepend(values ...E) { 70 // in reverse to keep passed order i.e. ["c","d"] -> Prepend(["a","b"]) -> ["a","b","c",d"] 71 for v := len(values) - 1; v >= 0; v-- { 72 newElement := &element[E]{value: values[v], next: list.first} 73 list.first = newElement 74 if list.size == 0 { 75 list.last = newElement 76 } 77 list.size++ 78 } 79 } 80 81 // Get returns the element at index. 82 // Second return parameter is true if index is within bounds of the array and array is not empty, otherwise false. 83 func (list *List[E]) Get(index int) (E, bool) { 84 85 if !list.withinRange(index) { 86 return list.zero, false 87 } 88 89 element := list.first 90 for e := 0; e != index; e, element = e+1, element.next { 91 } 92 93 return element.value, true 94 } 95 96 // Remove removes the element at the given index from the list. 97 func (list *List[E]) Remove(index int) { 98 99 if !list.withinRange(index) { 100 return 101 } 102 103 if list.size == 1 { 104 list.Clear() 105 return 106 } 107 108 var beforeElement *element[E] 109 element := list.first 110 for e := 0; e != index; e, element = e+1, element.next { 111 beforeElement = element 112 } 113 114 if element == list.first { 115 list.first = element.next 116 } 117 if element == list.last { 118 list.last = beforeElement 119 } 120 if beforeElement != nil { 121 beforeElement.next = element.next 122 } 123 124 element = nil 125 126 list.size-- 127 } 128 129 // Contains checks if values (one or more) are present in the set. 130 // All values have to be present in the set for the method to return true. 131 // Performance time complexity of n^2. 132 // Returns true if no arguments are passed at all, i.e. set is always super-set of empty set. 133 func (list *List[E]) Contains(values ...E) bool { 134 135 if len(values) == 0 { 136 return true 137 } 138 if list.size == 0 { 139 return false 140 } 141 for _, value := range values { 142 found := false 143 for element := list.first; element != nil; element = element.next { 144 if reflect.DeepEqual(element.value, value) { 145 found = true 146 break 147 } 148 } 149 if !found { 150 return false 151 } 152 } 153 return true 154 } 155 156 // Values returns all elements in the list. 157 func (list *List[E]) Values() []E { 158 values := make([]E, list.size, list.size) 159 for e, element := 0, list.first; element != nil; e, element = e+1, element.next { 160 values[e] = element.value 161 } 162 return values 163 } 164 165 // IndexOf returns index of provided element 166 func (list *List[E]) IndexOf(value E) int { 167 if list.size == 0 { 168 return -1 169 } 170 for index, element := range list.Values() { 171 if reflect.DeepEqual(element, value) { 172 return index 173 } 174 } 175 return -1 176 } 177 178 // Empty returns true if list does not contain any elements. 179 func (list *List[E]) Empty() bool { 180 return list.size == 0 181 } 182 183 // Size returns number of elements within the list. 184 func (list *List[E]) Size() int { 185 return list.size 186 } 187 188 // Clear removes all elements from the list. 189 func (list *List[E]) Clear() { 190 list.size = 0 191 list.first = nil 192 list.last = nil 193 } 194 195 // Sort sort values (in-place) using. 196 func (list *List[E]) Sort(comparator bcomparator.Comparator[E]) { 197 198 if list.size < 2 { 199 return 200 } 201 202 values := list.Values() 203 bcomparator.Sort(values, comparator) 204 205 list.Clear() 206 207 list.Add(values...) 208 209 } 210 211 // Swap swaps values of two elements at the given indices. 212 func (list *List[E]) Swap(i, j int) { 213 if list.withinRange(i) && list.withinRange(j) && i != j { 214 var element1, element2 *element[E] 215 for e, currentElement := 0, list.first; element1 == nil || element2 == nil; e, currentElement = e+1, currentElement.next { 216 switch e { 217 case i: 218 element1 = currentElement 219 case j: 220 element2 = currentElement 221 } 222 } 223 element1.value, element2.value = element2.value, element1.value 224 } 225 } 226 227 // Insert inserts values at specified index position shifting the value at that position (if any) and any subsequent elements to the right. 228 // Does not do anything if position is negative or bigger than list's size 229 // Note: position equal to list's size is valid, i.e. append. 230 func (list *List[E]) Insert(index int, values ...E) { 231 232 if !list.withinRange(index) { 233 // Append 234 if index == list.size { 235 list.Add(values...) 236 } 237 return 238 } 239 240 list.size += len(values) 241 242 var beforeElement *element[E] 243 foundElement := list.first 244 for e := 0; e != index; e, foundElement = e+1, foundElement.next { 245 beforeElement = foundElement 246 } 247 248 if foundElement == list.first { 249 oldNextElement := list.first 250 for i, value := range values { 251 newElement := &element[E]{value: value} 252 if i == 0 { 253 list.first = newElement 254 } else { 255 beforeElement.next = newElement 256 } 257 beforeElement = newElement 258 } 259 beforeElement.next = oldNextElement 260 } else { 261 oldNextElement := beforeElement.next 262 for _, value := range values { 263 newElement := &element[E]{value: value} 264 beforeElement.next = newElement 265 beforeElement = newElement 266 } 267 beforeElement.next = oldNextElement 268 } 269 } 270 271 // Set value at specified index 272 // Does not do anything if position is negative or bigger than list's size 273 // Note: position equal to list's size is valid, i.e. append. 274 func (list *List[E]) Set(index int, value E) { 275 276 if !list.withinRange(index) { 277 // Append 278 if index == list.size { 279 list.Add(value) 280 } 281 return 282 } 283 284 foundElement := list.first 285 for e := 0; e != index; { 286 e, foundElement = e+1, foundElement.next 287 } 288 foundElement.value = value 289 } 290 291 // String returns a string representation of container 292 func (list *List[E]) String() string { 293 b := strings.Builder{} 294 b.WriteString("SinglyLinkedList\n") 295 ln := 0 296 for element := list.first; element != nil; element = element.next { 297 b.WriteString(fmt.Sprintf("(index:%d value:%v) ", ln, element.value)) 298 ln++ 299 } 300 return b.String() 301 } 302 303 // Check that the index is within bounds of the list 304 func (list *List[E]) withinRange(index int) bool { 305 return index >= 0 && index < list.size 306 } 307 308 // UnmarshalJSON @implements json.Unmarshaler 309 func (list *List[E]) UnmarshalJSON(bytes []byte) error { 310 var elements []E 311 err := json.Unmarshal(bytes, &elements) 312 if err == nil { 313 list.Clear() 314 list.Add(elements...) 315 } 316 return err 317 } 318 319 // MarshalJSON @implements json.Marshaler 320 func (list *List[E]) MarshalJSON() ([]byte, error) { 321 return json.Marshal(list.Values()) 322 }