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