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