github.com/hdt3213/godis@v1.2.9/datastruct/list/linked.go (about) 1 package list 2 3 // LinkedList is doubly linked list 4 type LinkedList struct { 5 first *node 6 last *node 7 size int 8 } 9 10 type node struct { 11 val interface{} 12 prev *node 13 next *node 14 } 15 16 // Add adds value to the tail 17 func (list *LinkedList) Add(val interface{}) { 18 if list == nil { 19 panic("list is nil") 20 } 21 n := &node{ 22 val: val, 23 } 24 if list.last == nil { 25 // empty list 26 list.first = n 27 list.last = n 28 } else { 29 n.prev = list.last 30 list.last.next = n 31 list.last = n 32 } 33 list.size++ 34 } 35 36 func (list *LinkedList) find(index int) (n *node) { 37 if index < list.size/2 { 38 n = list.first 39 for i := 0; i < index; i++ { 40 n = n.next 41 } 42 } else { 43 n = list.last 44 for i := list.size - 1; i > index; i-- { 45 n = n.prev 46 } 47 } 48 return n 49 } 50 51 // Get returns value at the given index 52 func (list *LinkedList) Get(index int) (val interface{}) { 53 if list == nil { 54 panic("list is nil") 55 } 56 if index < 0 || index >= list.size { 57 panic("index out of bound") 58 } 59 return list.find(index).val 60 } 61 62 // Set updates value at the given index, the index should between [0, list.size] 63 func (list *LinkedList) Set(index int, val interface{}) { 64 if list == nil { 65 panic("list is nil") 66 } 67 if index < 0 || index > list.size { 68 panic("index out of bound") 69 } 70 n := list.find(index) 71 n.val = val 72 } 73 74 // Insert inserts value at the given index, the original element at the given index will move backward 75 func (list *LinkedList) Insert(index int, val interface{}) { 76 if list == nil { 77 panic("list is nil") 78 } 79 if index < 0 || index > list.size { 80 panic("index out of bound") 81 } 82 83 if index == list.size { 84 list.Add(val) 85 return 86 } 87 // list is not empty 88 pivot := list.find(index) 89 n := &node{ 90 val: val, 91 prev: pivot.prev, 92 next: pivot, 93 } 94 if pivot.prev == nil { 95 list.first = n 96 } else { 97 pivot.prev.next = n 98 } 99 pivot.prev = n 100 list.size++ 101 } 102 103 func (list *LinkedList) removeNode(n *node) { 104 if n.prev == nil { 105 list.first = n.next 106 } else { 107 n.prev.next = n.next 108 } 109 if n.next == nil { 110 list.last = n.prev 111 } else { 112 n.next.prev = n.prev 113 } 114 115 // for gc 116 n.prev = nil 117 n.next = nil 118 119 list.size-- 120 } 121 122 // Remove removes value at the given index 123 func (list *LinkedList) Remove(index int) (val interface{}) { 124 if list == nil { 125 panic("list is nil") 126 } 127 if index < 0 || index >= list.size { 128 panic("index out of bound") 129 } 130 131 n := list.find(index) 132 list.removeNode(n) 133 return n.val 134 } 135 136 // RemoveLast removes the last element and returns its value 137 func (list *LinkedList) RemoveLast() (val interface{}) { 138 if list == nil { 139 panic("list is nil") 140 } 141 if list.last == nil { 142 // empty list 143 return nil 144 } 145 n := list.last 146 list.removeNode(n) 147 return n.val 148 } 149 150 // RemoveAllByVal removes all elements with the given val 151 func (list *LinkedList) RemoveAllByVal(expected Expected) int { 152 if list == nil { 153 panic("list is nil") 154 } 155 n := list.first 156 removed := 0 157 var nextNode *node 158 for n != nil { 159 nextNode = n.next 160 if expected(n.val) { 161 list.removeNode(n) 162 removed++ 163 } 164 n = nextNode 165 } 166 return removed 167 } 168 169 // RemoveByVal removes at most `count` values of the specified value in this list 170 // scan from left to right 171 func (list *LinkedList) RemoveByVal(expected Expected, count int) int { 172 if list == nil { 173 panic("list is nil") 174 } 175 n := list.first 176 removed := 0 177 var nextNode *node 178 for n != nil { 179 nextNode = n.next 180 if expected(n.val) { 181 list.removeNode(n) 182 removed++ 183 } 184 if removed == count { 185 break 186 } 187 n = nextNode 188 } 189 return removed 190 } 191 192 // ReverseRemoveByVal removes at most `count` values of the specified value in this list 193 // scan from right to left 194 func (list *LinkedList) ReverseRemoveByVal(expected Expected, count int) int { 195 if list == nil { 196 panic("list is nil") 197 } 198 n := list.last 199 removed := 0 200 var prevNode *node 201 for n != nil { 202 prevNode = n.prev 203 if expected(n.val) { 204 list.removeNode(n) 205 removed++ 206 } 207 if removed == count { 208 break 209 } 210 n = prevNode 211 } 212 return removed 213 } 214 215 // Len returns the number of elements in list 216 func (list *LinkedList) Len() int { 217 if list == nil { 218 panic("list is nil") 219 } 220 return list.size 221 } 222 223 // ForEach visits each element in the list 224 // if the consumer returns false, the loop will be break 225 func (list *LinkedList) ForEach(consumer Consumer) { 226 if list == nil { 227 panic("list is nil") 228 } 229 n := list.first 230 i := 0 231 for n != nil { 232 goNext := consumer(i, n.val) 233 if !goNext { 234 break 235 } 236 i++ 237 n = n.next 238 } 239 } 240 241 // Contains returns whether the given value exist in the list 242 func (list *LinkedList) Contains(expected Expected) bool { 243 contains := false 244 list.ForEach(func(i int, actual interface{}) bool { 245 if expected(actual) { 246 contains = true 247 return false 248 } 249 return true 250 }) 251 return contains 252 } 253 254 // Range returns elements which index within [start, stop) 255 func (list *LinkedList) Range(start int, stop int) []interface{} { 256 if list == nil { 257 panic("list is nil") 258 } 259 if start < 0 || start >= list.size { 260 panic("`start` out of range") 261 } 262 if stop < start || stop > list.size { 263 panic("`stop` out of range") 264 } 265 266 sliceSize := stop - start 267 slice := make([]interface{}, sliceSize) 268 n := list.first 269 i := 0 270 sliceIndex := 0 271 for n != nil { 272 if i >= start && i < stop { 273 slice[sliceIndex] = n.val 274 sliceIndex++ 275 } else if i >= stop { 276 break 277 } 278 i++ 279 n = n.next 280 } 281 return slice 282 } 283 284 // Make creates a new linked list 285 func Make(vals ...interface{}) *LinkedList { 286 list := LinkedList{} 287 for _, v := range vals { 288 list.Add(v) 289 } 290 return &list 291 }