github.com/mymmsc/gox@v1.3.33/util/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/mymmsc/gox/util"
    15  	"strings"
    16  )
    17  
    18  func assertListImplementation() {
    19  	var _ util.List = (*List)(nil)
    20  }
    21  
    22  // List holds the elements, where each element points to the next and previous element
    23  type List struct {
    24  	first *element
    25  	last  *element
    26  	size  int
    27  }
    28  
    29  type element struct {
    30  	value interface{}
    31  	prev  *element
    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, prev: list.last}
    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  		if list.size == 0 {
    70  			list.first = newElement
    71  			list.last = newElement
    72  		} else {
    73  			list.first.prev = newElement
    74  			list.first = newElement
    75  		}
    76  		list.size++
    77  	}
    78  }
    79  
    80  // Get returns the element at index.
    81  // Second return parameter is true if index is within bounds of the array and array is not empty, otherwise false.
    82  func (list *List) Get(index int) (interface{}, bool) {
    83  
    84  	if !list.withinRange(index) {
    85  		return nil, false
    86  	}
    87  
    88  	// determine traveral direction, last to first or first to last
    89  	if list.size-index < index {
    90  		element := list.last
    91  		for e := list.size - 1; e != index; e, element = e-1, element.prev {
    92  		}
    93  		return element.value, true
    94  	}
    95  	element := list.first
    96  	for e := 0; e != index; e, element = e+1, element.next {
    97  	}
    98  	return element.value, true
    99  }
   100  
   101  // Remove removes the element at the given index from the list.
   102  func (list *List) Remove(index int) {
   103  
   104  	if !list.withinRange(index) {
   105  		return
   106  	}
   107  
   108  	if list.size == 1 {
   109  		list.Clear()
   110  		return
   111  	}
   112  
   113  	var element *element
   114  	// determine traversal direction, last to first or first to last
   115  	if list.size-index < index {
   116  		element = list.last
   117  		for e := list.size - 1; e != index; e, element = e-1, element.prev {
   118  		}
   119  	} else {
   120  		element = list.first
   121  		for e := 0; e != index; e, element = e+1, element.next {
   122  		}
   123  	}
   124  
   125  	if element == list.first {
   126  		list.first = element.next
   127  	}
   128  	if element == list.last {
   129  		list.last = element.prev
   130  	}
   131  	if element.prev != nil {
   132  		element.prev.next = element.next
   133  	}
   134  	if element.next != nil {
   135  		element.next.prev = element.prev
   136  	}
   137  
   138  	element = nil
   139  
   140  	list.size--
   141  }
   142  
   143  // Contains check if values (one or more) are present in the set.
   144  // All values have to be present in the set for the method to return true.
   145  // Performance time complexity of n^2.
   146  // Returns true if no arguments are passed at all, i.e. set is always super-set of empty set.
   147  func (list *List) Contains(values ...interface{}) bool {
   148  
   149  	if len(values) == 0 {
   150  		return true
   151  	}
   152  	if list.size == 0 {
   153  		return false
   154  	}
   155  	for _, value := range values {
   156  		found := false
   157  		for element := list.first; element != nil; element = element.next {
   158  			if element.value == value {
   159  				found = true
   160  				break
   161  			}
   162  		}
   163  		if !found {
   164  			return false
   165  		}
   166  	}
   167  	return true
   168  }
   169  
   170  // Values returns all elements in the list.
   171  func (list *List) Values() []interface{} {
   172  	values := make([]interface{}, list.size, list.size)
   173  	for e, element := 0, list.first; element != nil; e, element = e+1, element.next {
   174  		values[e] = element.value
   175  	}
   176  	return values
   177  }
   178  
   179  //IndexOf returns index of provided element
   180  func (list *List) IndexOf(value interface{}) int {
   181  	if list.size == 0 {
   182  		return -1
   183  	}
   184  	for index, element := range list.Values() {
   185  		if element == value {
   186  			return index
   187  		}
   188  	}
   189  	return -1
   190  }
   191  
   192  // Empty returns true if list does not contain any elements.
   193  func (list *List) Empty() bool {
   194  	return list.size == 0
   195  }
   196  
   197  // Size returns number of elements within the list.
   198  func (list *List) Size() int {
   199  	return list.size
   200  }
   201  
   202  // Clear removes all elements from the list.
   203  func (list *List) Clear() {
   204  	list.size = 0
   205  	list.first = nil
   206  	list.last = nil
   207  }
   208  
   209  // Sort sorts values (in-place) using.
   210  func (list *List) Sort(comparator util.Comparator) {
   211  
   212  	if list.size < 2 {
   213  		return
   214  	}
   215  
   216  	values := list.Values()
   217  	util.Sort(values, comparator)
   218  
   219  	list.Clear()
   220  
   221  	list.Add(values...)
   222  
   223  }
   224  
   225  // Swap swaps values of two elements at the given indices.
   226  func (list *List) Swap(i, j int) {
   227  	if list.withinRange(i) && list.withinRange(j) && i != j {
   228  		var element1, element2 *element
   229  		for e, currentElement := 0, list.first; element1 == nil || element2 == nil; e, currentElement = e+1, currentElement.next {
   230  			switch e {
   231  			case i:
   232  				element1 = currentElement
   233  			case j:
   234  				element2 = currentElement
   235  			}
   236  		}
   237  		element1.value, element2.value = element2.value, element1.value
   238  	}
   239  }
   240  
   241  // Insert inserts values at specified index position shifting the value at that position (if any) and any subsequent elements to the right.
   242  // Does not do anything if position is negative or bigger than list's size
   243  // Note: position equal to list's size is valid, i.e. append.
   244  func (list *List) Insert(index int, values ...interface{}) {
   245  
   246  	if !list.withinRange(index) {
   247  		// Append
   248  		if index == list.size {
   249  			list.Add(values...)
   250  		}
   251  		return
   252  	}
   253  
   254  	list.size += len(values)
   255  
   256  	var beforeElement *element
   257  	var foundElement *element
   258  	// determine traversal direction, last to first or first to last
   259  	if list.size-index < index {
   260  		foundElement = list.last
   261  		for e := list.size - 1; e != index; e, foundElement = e-1, foundElement.prev {
   262  			beforeElement = foundElement.prev
   263  		}
   264  	} else {
   265  		foundElement = list.first
   266  		for e := 0; e != index; e, foundElement = e+1, foundElement.next {
   267  			beforeElement = foundElement
   268  		}
   269  	}
   270  
   271  	if foundElement == list.first {
   272  		oldNextElement := list.first
   273  		for i, value := range values {
   274  			newElement := &element{value: value}
   275  			if i == 0 {
   276  				list.first = newElement
   277  			} else {
   278  				newElement.prev = beforeElement
   279  				beforeElement.next = newElement
   280  			}
   281  			beforeElement = newElement
   282  		}
   283  		oldNextElement.prev = beforeElement
   284  		beforeElement.next = oldNextElement
   285  	} else {
   286  		oldNextElement := beforeElement.next
   287  		for _, value := range values {
   288  			newElement := &element{value: value}
   289  			newElement.prev = beforeElement
   290  			beforeElement.next = newElement
   291  			beforeElement = newElement
   292  		}
   293  		oldNextElement.prev = beforeElement
   294  		beforeElement.next = oldNextElement
   295  	}
   296  }
   297  
   298  // Set value at specified index position
   299  // Does not do anything if position is negative or bigger than list's size
   300  // Note: position equal to list's size is valid, i.e. append.
   301  func (list *List) Set(index int, value interface{}) {
   302  
   303  	if !list.withinRange(index) {
   304  		// Append
   305  		if index == list.size {
   306  			list.Add(value)
   307  		}
   308  		return
   309  	}
   310  
   311  	var foundElement *element
   312  	// determine traversal direction, last to first or first to last
   313  	if list.size-index < index {
   314  		foundElement = list.last
   315  		for e := list.size - 1; e != index; {
   316  			fmt.Println("Set last", index, value, foundElement, foundElement.prev)
   317  			e, foundElement = e-1, foundElement.prev
   318  		}
   319  	} else {
   320  		foundElement = list.first
   321  		for e := 0; e != index; {
   322  			e, foundElement = e+1, foundElement.next
   323  		}
   324  	}
   325  
   326  	foundElement.value = value
   327  }
   328  
   329  // String returns a string representation of container
   330  func (list *List) String() string {
   331  	str := "DoublyLinkedList\n"
   332  	values := []string{}
   333  	for element := list.first; element != nil; element = element.next {
   334  		values = append(values, fmt.Sprintf("%v", element.value))
   335  	}
   336  	str += strings.Join(values, ", ")
   337  	return str
   338  }
   339  
   340  // Check that the index is within bounds of the list
   341  func (list *List) withinRange(index int) bool {
   342  	return index >= 0 && index < list.size
   343  }