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