github.com/songzhibin97/go-baseutils@v0.0.2-0.20240302024150-487d8ce9c082/structure/lists/doublylinkedlist/doublylinkedlist.go (about)

     1  // Package doublylinkedlist implements the doubly-linked list.
     2  //
     3  // Structure is not thread safe.
     4  //
     5  // Reference: https://en.wikipedia.org/wiki/List_%28abstract_data_type%29
     6  package doublylinkedlist
     7  
     8  import (
     9  	"encoding/json"
    10  	"fmt"
    11  	"github.com/songzhibin97/go-baseutils/base/bcomparator"
    12  	"github.com/songzhibin97/go-baseutils/structure/lists"
    13  	"reflect"
    14  	"strings"
    15  )
    16  
    17  // Assert List implementation
    18  var _ lists.List[any] = (*List[any])(nil)
    19  
    20  // List holds the elements, where each element points to the next and previous element
    21  type List[E any] struct {
    22  	first *element[E]
    23  	last  *element[E]
    24  	size  int
    25  	zero  E
    26  }
    27  
    28  type element[E any] struct {
    29  	value E
    30  	prev  *element[E]
    31  	next  *element[E]
    32  }
    33  
    34  // New instantiates a new list and adds the passed values, if any, to the list
    35  func New[E any](values ...E) *List[E] {
    36  	list := &List[E]{}
    37  	if len(values) > 0 {
    38  		list.Add(values...)
    39  	}
    40  	return list
    41  }
    42  
    43  // Add appends a value (one or more) at the end of the list (same as Append())
    44  func (list *List[E]) Add(values ...E) {
    45  	for _, value := range values {
    46  		newElement := &element[E]{value: value, prev: list.last}
    47  		if list.size == 0 {
    48  			list.first = newElement
    49  			list.last = newElement
    50  		} else {
    51  			list.last.next = newElement
    52  			list.last = newElement
    53  		}
    54  		list.size++
    55  	}
    56  }
    57  
    58  // Append appends a value (one or more) at the end of the list (same as Add())
    59  func (list *List[E]) Append(values ...E) {
    60  	list.Add(values...)
    61  }
    62  
    63  // Prepend prepends a values (or more)
    64  func (list *List[E]) Prepend(values ...E) {
    65  	// in reverse to keep passed order i.e. ["c","d"] -> Prepend(["a","b"]) -> ["a","b","c",d"]
    66  	for v := len(values) - 1; v >= 0; v-- {
    67  		newElement := &element[E]{value: values[v], next: list.first}
    68  		if list.size == 0 {
    69  			list.first = newElement
    70  			list.last = newElement
    71  		} else {
    72  			list.first.prev = newElement
    73  			list.first = newElement
    74  		}
    75  		list.size++
    76  	}
    77  }
    78  
    79  // Get returns the element at index.
    80  // Second return parameter is true if index is within bounds of the array and array is not empty, otherwise false.
    81  func (list *List[E]) Get(index int) (E, bool) {
    82  
    83  	if !list.withinRange(index) {
    84  		return list.zero, false
    85  	}
    86  
    87  	// determine traveral direction, last to first or first to last
    88  	if list.size-index < index {
    89  		element := list.last
    90  		for e := list.size - 1; e != index; e, element = e-1, element.prev {
    91  		}
    92  		return element.value, true
    93  	}
    94  	element := list.first
    95  	for e := 0; e != index; e, element = e+1, element.next {
    96  	}
    97  	return element.value, true
    98  }
    99  
   100  // Remove removes the element at the given index from the list.
   101  func (list *List[E]) Remove(index int) {
   102  
   103  	if !list.withinRange(index) {
   104  		return
   105  	}
   106  
   107  	if list.size == 1 {
   108  		list.Clear()
   109  		return
   110  	}
   111  
   112  	var element *element[E]
   113  	// determine traversal direction, last to first or first to last
   114  	if list.size-index < index {
   115  		element = list.last
   116  		for e := list.size - 1; e != index; e, element = e-1, element.prev {
   117  		}
   118  	} else {
   119  		element = list.first
   120  		for e := 0; e != index; e, element = e+1, element.next {
   121  		}
   122  	}
   123  
   124  	if element == list.first {
   125  		list.first = element.next
   126  	}
   127  	if element == list.last {
   128  		list.last = element.prev
   129  	}
   130  	if element.prev != nil {
   131  		element.prev.next = element.next
   132  	}
   133  	if element.next != nil {
   134  		element.next.prev = element.prev
   135  	}
   136  
   137  	element = nil
   138  
   139  	list.size--
   140  }
   141  
   142  // Contains check if values (one or more) are present in the set.
   143  // All values have to be present in the set for the method to return true.
   144  // Performance time complexity of n^2.
   145  // Returns true if no arguments are passed at all, i.e. set is always super-set of empty set.
   146  func (list *List[E]) Contains(values ...E) bool {
   147  
   148  	if len(values) == 0 {
   149  		return true
   150  	}
   151  	if list.size == 0 {
   152  		return false
   153  	}
   154  	for _, value := range values {
   155  		found := false
   156  		for element := list.first; element != nil; element = element.next {
   157  			if reflect.DeepEqual(element.value, value) {
   158  				found = true
   159  				break
   160  			}
   161  		}
   162  		if !found {
   163  			return false
   164  		}
   165  	}
   166  	return true
   167  }
   168  
   169  // Values returns all elements in the list.
   170  func (list *List[E]) Values() []E {
   171  	values := make([]E, list.size, list.size)
   172  	for e, element := 0, list.first; element != nil; e, element = e+1, element.next {
   173  		values[e] = element.value
   174  	}
   175  	return values
   176  }
   177  
   178  // IndexOf returns index of provided element
   179  func (list *List[E]) IndexOf(value E) int {
   180  	if list.size == 0 {
   181  		return -1
   182  	}
   183  	for index, element := range list.Values() {
   184  		if reflect.DeepEqual(element, value) {
   185  			return index
   186  		}
   187  	}
   188  	return -1
   189  }
   190  
   191  // Empty returns true if list does not contain any elements.
   192  func (list *List[E]) Empty() bool {
   193  	return list.size == 0
   194  }
   195  
   196  // Size returns number of elements within the list.
   197  func (list *List[E]) Size() int {
   198  	return list.size
   199  }
   200  
   201  // Clear removes all elements from the list.
   202  func (list *List[E]) Clear() {
   203  	list.size = 0
   204  	list.first = nil
   205  	list.last = nil
   206  }
   207  
   208  // Sort sorts values (in-place) using.
   209  func (list *List[E]) Sort(comparator bcomparator.Comparator[E]) {
   210  
   211  	if list.size < 2 {
   212  		return
   213  	}
   214  
   215  	values := list.Values()
   216  	bcomparator.Sort(values, comparator)
   217  
   218  	list.Clear()
   219  
   220  	list.Add(values...)
   221  
   222  }
   223  
   224  // Swap swaps values of two elements at the given indices.
   225  func (list *List[E]) Swap(i, j int) {
   226  	if list.withinRange(i) && list.withinRange(j) && i != j {
   227  		var element1, element2 *element[E]
   228  		for e, currentElement := 0, list.first; element1 == nil || element2 == nil; e, currentElement = e+1, currentElement.next {
   229  			switch e {
   230  			case i:
   231  				element1 = currentElement
   232  			case j:
   233  				element2 = currentElement
   234  			}
   235  		}
   236  		element1.value, element2.value = element2.value, element1.value
   237  	}
   238  }
   239  
   240  // Insert inserts values at specified index position shifting the value at that position (if any) and any subsequent elements to the right.
   241  // Does not do anything if position is negative or bigger than list's size
   242  // Note: position equal to list's size is valid, i.e. append.
   243  func (list *List[E]) Insert(index int, values ...E) {
   244  
   245  	if !list.withinRange(index) {
   246  		// Append
   247  		if index == list.size {
   248  			list.Add(values...)
   249  		}
   250  		return
   251  	}
   252  
   253  	list.size += len(values)
   254  
   255  	var beforeElement *element[E]
   256  	var foundElement *element[E]
   257  	// determine traversal direction, last to first or first to last
   258  	if list.size-index < index {
   259  		foundElement = list.last
   260  		for e := list.size - 1; e != index; e, foundElement = e-1, foundElement.prev {
   261  			beforeElement = foundElement.prev
   262  		}
   263  	} else {
   264  		foundElement = list.first
   265  		for e := 0; e != index; e, foundElement = e+1, foundElement.next {
   266  			beforeElement = foundElement
   267  		}
   268  	}
   269  
   270  	if foundElement == list.first {
   271  		oldNextElement := list.first
   272  		for i, value := range values {
   273  			newElement := &element[E]{value: value}
   274  			if i == 0 {
   275  				list.first = newElement
   276  			} else {
   277  				newElement.prev = beforeElement
   278  				beforeElement.next = newElement
   279  			}
   280  			beforeElement = newElement
   281  		}
   282  		oldNextElement.prev = beforeElement
   283  		beforeElement.next = oldNextElement
   284  	} else {
   285  		oldNextElement := beforeElement.next
   286  		for _, value := range values {
   287  			newElement := &element[E]{value: value}
   288  			newElement.prev = beforeElement
   289  			beforeElement.next = newElement
   290  			beforeElement = newElement
   291  		}
   292  		oldNextElement.prev = beforeElement
   293  		beforeElement.next = oldNextElement
   294  	}
   295  }
   296  
   297  // Set value at specified index position
   298  // Does not do anything if position is negative or bigger than list's size
   299  // Note: position equal to list's size is valid, i.e. append.
   300  func (list *List[E]) Set(index int, value E) {
   301  
   302  	if !list.withinRange(index) {
   303  		// Append
   304  		if index == list.size {
   305  			list.Add(value)
   306  		}
   307  		return
   308  	}
   309  
   310  	var foundElement *element[E]
   311  	// determine traversal direction, last to first or first to last
   312  	if list.size-index < index {
   313  		foundElement = list.last
   314  		for e := list.size - 1; e != index; {
   315  			fmt.Println("Set last", index, value, foundElement, foundElement.prev)
   316  			e, foundElement = e-1, foundElement.prev
   317  		}
   318  	} else {
   319  		foundElement = list.first
   320  		for e := 0; e != index; {
   321  			e, foundElement = e+1, foundElement.next
   322  		}
   323  	}
   324  
   325  	foundElement.value = value
   326  }
   327  
   328  // String returns a string representation of container
   329  func (list *List[E]) String() string {
   330  	b := strings.Builder{}
   331  	b.WriteString("DoublyLinkedList\n")
   332  	ln := 0
   333  	for element := list.first; element != nil; element = element.next {
   334  		b.WriteString(fmt.Sprintf("(index:%d value:%v) ", ln, element.value))
   335  		ln++
   336  	}
   337  	return b.String()
   338  }
   339  
   340  // Check that the index is within bounds of the list
   341  func (list *List[E]) withinRange(index int) bool {
   342  	return index >= 0 && index < list.size
   343  }
   344  
   345  // UnmarshalJSON @implements json.Unmarshaler
   346  func (list *List[E]) UnmarshalJSON(bytes []byte) error {
   347  	var elements []E
   348  	err := json.Unmarshal(bytes, &elements)
   349  	if err == nil {
   350  		list.Clear()
   351  		list.Add(elements...)
   352  	}
   353  	return err
   354  }
   355  
   356  // MarshalJSON @implements json.Marshaler
   357  func (list *List[E]) MarshalJSON() ([]byte, error) {
   358  	return json.Marshal(list.Values())
   359  }