github.com/mymmsc/gox@v1.3.33/util/singlylinkedlist/singlylinkedlist.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 singlylinkedlist implements the singly-linked list. 6 // 7 // Structure is not thread safe. 8 // 9 // Reference: https://en.wikipedia.org/wiki/List_%28abstract_data_type%29 10 package singlylinkedlist 11 12 import ( 13 "fmt" 14 "strings" 15 16 "github.com/mymmsc/gox/util" 17 ) 18 19 func assertListImplementation() { 20 var _ util.List = (*List)(nil) 21 } 22 23 // List holds the elements, where each element points to the next element 24 type List struct { 25 first *element 26 last *element 27 size int 28 } 29 30 type element struct { 31 value interface{} 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} 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 list.first = newElement 70 if list.size == 0 { 71 list.last = newElement 72 } 73 list.size++ 74 } 75 } 76 77 // Get returns the element at index. 78 // Second return parameter is true if index is within bounds of the array and array is not empty, otherwise false. 79 func (list *List) Get(index int) (interface{}, bool) { 80 81 if !list.withinRange(index) { 82 return nil, false 83 } 84 85 element := list.first 86 for e := 0; e != index; e, element = e+1, element.next { 87 } 88 89 return element.value, true 90 } 91 92 // Remove removes the element at the given index from the list. 93 func (list *List) Remove(index int) { 94 95 if !list.withinRange(index) { 96 return 97 } 98 99 if list.size == 1 { 100 list.Clear() 101 return 102 } 103 104 var beforeElement *element 105 element := list.first 106 for e := 0; e != index; e, element = e+1, element.next { 107 beforeElement = element 108 } 109 110 if element == list.first { 111 list.first = element.next 112 } 113 if element == list.last { 114 list.last = beforeElement 115 } 116 if beforeElement != nil { 117 beforeElement.next = element.next 118 } 119 120 element = nil 121 122 list.size-- 123 } 124 125 // Contains checks if values (one or more) are present in the set. 126 // All values have to be present in the set for the method to return true. 127 // Performance time complexity of n^2. 128 // Returns true if no arguments are passed at all, i.e. set is always super-set of empty set. 129 func (list *List) Contains(values ...interface{}) bool { 130 131 if len(values) == 0 { 132 return true 133 } 134 if list.size == 0 { 135 return false 136 } 137 for _, value := range values { 138 found := false 139 for element := list.first; element != nil; element = element.next { 140 if element.value == value { 141 found = true 142 break 143 } 144 } 145 if !found { 146 return false 147 } 148 } 149 return true 150 } 151 152 // Values returns all elements in the list. 153 func (list *List) Values() []interface{} { 154 values := make([]interface{}, list.size, list.size) 155 for e, element := 0, list.first; element != nil; e, element = e+1, element.next { 156 values[e] = element.value 157 } 158 return values 159 } 160 161 //IndexOf returns index of provided element 162 func (list *List) IndexOf(value interface{}) int { 163 if list.size == 0 { 164 return -1 165 } 166 for index, element := range list.Values() { 167 if element == value { 168 return index 169 } 170 } 171 return -1 172 } 173 174 // Empty returns true if list does not contain any elements. 175 func (list *List) Empty() bool { 176 return list.size == 0 177 } 178 179 // Size returns number of elements within the list. 180 func (list *List) Size() int { 181 return list.size 182 } 183 184 // Clear removes all elements from the list. 185 func (list *List) Clear() { 186 list.size = 0 187 list.first = nil 188 list.last = nil 189 } 190 191 // Sort sort values (in-place) using. 192 func (list *List) Sort(comparator util.Comparator) { 193 194 if list.size < 2 { 195 return 196 } 197 198 values := list.Values() 199 util.Sort(values, comparator) 200 201 list.Clear() 202 203 list.Add(values...) 204 205 } 206 207 // Swap swaps values of two elements at the given indices. 208 func (list *List) Swap(i, j int) { 209 if list.withinRange(i) && list.withinRange(j) && i != j { 210 var element1, element2 *element 211 for e, currentElement := 0, list.first; element1 == nil || element2 == nil; e, currentElement = e+1, currentElement.next { 212 switch e { 213 case i: 214 element1 = currentElement 215 case j: 216 element2 = currentElement 217 } 218 } 219 element1.value, element2.value = element2.value, element1.value 220 } 221 } 222 223 // Insert inserts values at specified index position shifting the value at that position (if any) and any subsequent elements to the right. 224 // Does not do anything if position is negative or bigger than list's size 225 // Note: position equal to list's size is valid, i.e. append. 226 func (list *List) Insert(index int, values ...interface{}) { 227 228 if !list.withinRange(index) { 229 // Append 230 if index == list.size { 231 list.Add(values...) 232 } 233 return 234 } 235 236 list.size += len(values) 237 238 var beforeElement *element 239 foundElement := list.first 240 for e := 0; e != index; e, foundElement = e+1, foundElement.next { 241 beforeElement = foundElement 242 } 243 244 if foundElement == list.first { 245 oldNextElement := list.first 246 for i, value := range values { 247 newElement := &element{value: value} 248 if i == 0 { 249 list.first = newElement 250 } else { 251 beforeElement.next = newElement 252 } 253 beforeElement = newElement 254 } 255 beforeElement.next = oldNextElement 256 } else { 257 oldNextElement := beforeElement.next 258 for _, value := range values { 259 newElement := &element{value: value} 260 beforeElement.next = newElement 261 beforeElement = newElement 262 } 263 beforeElement.next = oldNextElement 264 } 265 } 266 267 // Set value at specified index 268 // Does not do anything if position is negative or bigger than list's size 269 // Note: position equal to list's size is valid, i.e. append. 270 func (list *List) Set(index int, value interface{}) { 271 272 if !list.withinRange(index) { 273 // Append 274 if index == list.size { 275 list.Add(value) 276 } 277 return 278 } 279 280 foundElement := list.first 281 for e := 0; e != index; { 282 e, foundElement = e+1, foundElement.next 283 } 284 foundElement.value = value 285 } 286 287 // String returns a string representation of container 288 func (list *List) String() string { 289 str := "SinglyLinkedList\n" 290 values := []string{} 291 for element := list.first; element != nil; element = element.next { 292 values = append(values, fmt.Sprintf("%v", element.value)) 293 } 294 str += strings.Join(values, ", ") 295 return str 296 } 297 298 // Check that the index is within bounds of the list 299 func (list *List) withinRange(index int) bool { 300 return index >= 0 && index < list.size 301 }