github.com/alexandrestein/gods@v1.0.1/lists/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 "github.com/alexandrestein/gods/lists" 15 "github.com/alexandrestein/gods/utils" 16 "strings" 17 ) 18 19 func assertListImplementation() { 20 var _ lists.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 empty list 36 func New() *List { 37 return &List{} 38 } 39 40 // Add appends a value (one or more) at the end of the list (same as Append()) 41 func (list *List) Add(values ...interface{}) { 42 for _, value := range values { 43 newElement := &element{value: value} 44 if list.size == 0 { 45 list.first = newElement 46 list.last = newElement 47 } else { 48 list.last.next = newElement 49 list.last = newElement 50 } 51 list.size++ 52 } 53 } 54 55 // Append appends a value (one or more) at the end of the list (same as Add()) 56 func (list *List) Append(values ...interface{}) { 57 list.Add(values...) 58 } 59 60 // Prepend prepends a values (or more) 61 func (list *List) Prepend(values ...interface{}) { 62 // in reverse to keep passed order i.e. ["c","d"] -> Prepend(["a","b"]) -> ["a","b","c",d"] 63 for v := len(values) - 1; v >= 0; v-- { 64 newElement := &element{value: values[v], next: list.first} 65 list.first = newElement 66 if list.size == 0 { 67 list.last = newElement 68 } 69 list.size++ 70 } 71 } 72 73 // Get returns the element at index. 74 // Second return parameter is true if index is within bounds of the array and array is not empty, otherwise false. 75 func (list *List) Get(index int) (interface{}, bool) { 76 77 if !list.withinRange(index) { 78 return nil, false 79 } 80 81 element := list.first 82 for e := 0; e != index; e, element = e+1, element.next { 83 } 84 85 return element.value, true 86 } 87 88 // Remove removes one or more elements from the list with the supplied indices. 89 func (list *List) Remove(index int) { 90 91 if !list.withinRange(index) { 92 return 93 } 94 95 if list.size == 1 { 96 list.Clear() 97 return 98 } 99 100 var beforeElement *element 101 element := list.first 102 for e := 0; e != index; e, element = e+1, element.next { 103 beforeElement = element 104 } 105 106 if element == list.first { 107 list.first = element.next 108 } 109 if element == list.last { 110 list.last = beforeElement 111 } 112 if beforeElement != nil { 113 beforeElement.next = element.next 114 } 115 116 element = nil 117 118 list.size-- 119 } 120 121 // Contains checks if values (one or more) are present in the set. 122 // All values have to be present in the set for the method to return true. 123 // Performance time complexity of n^2. 124 // Returns true if no arguments are passed at all, i.e. set is always super-set of empty set. 125 func (list *List) Contains(values ...interface{}) bool { 126 127 if len(values) == 0 { 128 return true 129 } 130 if list.size == 0 { 131 return false 132 } 133 for _, value := range values { 134 found := false 135 for element := list.first; element != nil; element = element.next { 136 if element.value == value { 137 found = true 138 break 139 } 140 } 141 if !found { 142 return false 143 } 144 } 145 return true 146 } 147 148 // Values returns all elements in the list. 149 func (list *List) Values() []interface{} { 150 values := make([]interface{}, list.size, list.size) 151 for e, element := 0, list.first; element != nil; e, element = e+1, element.next { 152 values[e] = element.value 153 } 154 return values 155 } 156 157 //IndexOf returns index of provided element 158 func (list *List) IndexOf(value interface{}) int{ 159 if list.size == 0 { 160 return -1 161 } 162 for index, element := range list.Values() { 163 if element == value { 164 return index 165 } 166 } 167 return -1 168 } 169 // Empty returns true if list does not contain any elements. 170 func (list *List) Empty() bool { 171 return list.size == 0 172 } 173 174 // Size returns number of elements within the list. 175 func (list *List) Size() int { 176 return list.size 177 } 178 179 // Clear removes all elements from the list. 180 func (list *List) Clear() { 181 list.size = 0 182 list.first = nil 183 list.last = nil 184 } 185 186 // Sort sort values (in-place) using. 187 func (list *List) Sort(comparator utils.Comparator) { 188 189 if list.size < 2 { 190 return 191 } 192 193 values := list.Values() 194 utils.Sort(values, comparator) 195 196 list.Clear() 197 198 list.Add(values...) 199 200 } 201 202 // Swap swaps values of two elements at the given indices. 203 func (list *List) Swap(i, j int) { 204 if list.withinRange(i) && list.withinRange(j) && i != j { 205 var element1, element2 *element 206 for e, currentElement := 0, list.first; element1 == nil || element2 == nil; e, currentElement = e+1, currentElement.next { 207 switch e { 208 case i: 209 element1 = currentElement 210 case j: 211 element2 = currentElement 212 } 213 } 214 element1.value, element2.value = element2.value, element1.value 215 } 216 } 217 218 // Insert inserts values at specified index position shifting the value at that position (if any) and any subsequent elements to the right. 219 // Does not do anything if position is negative or bigger than list's size 220 // Note: position equal to list's size is valid, i.e. append. 221 func (list *List) Insert(index int, values ...interface{}) { 222 223 if !list.withinRange(index) { 224 // Append 225 if index == list.size { 226 list.Add(values...) 227 } 228 return 229 } 230 231 list.size += len(values) 232 233 var beforeElement *element 234 foundElement := list.first 235 for e := 0; e != index; e, foundElement = e+1, foundElement.next { 236 beforeElement = foundElement 237 } 238 239 if foundElement == list.first { 240 oldNextElement := list.first 241 for i, value := range values { 242 newElement := &element{value: value} 243 if i == 0 { 244 list.first = newElement 245 } else { 246 beforeElement.next = newElement 247 } 248 beforeElement = newElement 249 } 250 beforeElement.next = oldNextElement 251 } else { 252 oldNextElement := beforeElement.next 253 for _, value := range values { 254 newElement := &element{value: value} 255 beforeElement.next = newElement 256 beforeElement = newElement 257 } 258 beforeElement.next = oldNextElement 259 } 260 } 261 262 // String returns a string representation of container 263 func (list *List) String() string { 264 str := "SinglyLinkedList\n" 265 values := []string{} 266 for element := list.first; element != nil; element = element.next { 267 values = append(values, fmt.Sprintf("%v", element.value)) 268 } 269 str += strings.Join(values, ", ") 270 return str 271 } 272 273 // Check that the index is within bounds of the list 274 func (list *List) withinRange(index int) bool { 275 return index >= 0 && index < list.size 276 }