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  }