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  }