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