github.com/Nigel2392/go-datastructures@v1.1.5/linkedlist/singly.go (about)

     1  package linkedlist
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"strings"
     7  )
     8  
     9  // A singly linked list.
    10  //
    11  // This is a generic type, so you can use it with any type.
    12  //
    13  // For example, Singly[int] is a linked list of integers.
    14  //
    15  // If using an uncomparable type, the Remove(value) method will not work.
    16  //
    17  // You can only use RemoveIndex(index).
    18  type Singly[T any] struct {
    19  	head *Node[T]
    20  	len  int
    21  }
    22  
    23  // Returns the length of the list.
    24  func (l *Singly[T]) Len() int {
    25  	return l.len
    26  }
    27  
    28  // Returns the list as a string.
    29  func (l *Singly[T]) String() string {
    30  	var b strings.Builder
    31  	b.WriteString("[")
    32  	for n := l.head; n != nil; n = n.next {
    33  		fmt.Fprintf(&b, "%v", n.value)
    34  		if n.next != nil {
    35  			b.WriteString(", ")
    36  		}
    37  	}
    38  	b.WriteString("]")
    39  	return b.String()
    40  }
    41  
    42  // Returns the head of the list.
    43  func (l *Singly[T]) Head() *Node[T] {
    44  	return l.head
    45  }
    46  
    47  // Prepend a value to the beginning of the list.
    48  func (l *Singly[T]) Prepend(v T) {
    49  	var n = &Node[T]{value: v}
    50  	l.prepend(n)
    51  }
    52  
    53  // Shift a value from the beginning of the list.
    54  //
    55  // Returns the value that was shifted.
    56  func (l *Singly[T]) Shift() T {
    57  	if l.len == 0 {
    58  		panic("cannot shift from an empty list")
    59  	}
    60  	var v = l.head.value
    61  	l.RemoveIndex(0)
    62  	return v
    63  }
    64  
    65  // Reset the list.
    66  func (l *Singly[T]) Reset() {
    67  	l.head = nil
    68  	l.len = 0
    69  }
    70  
    71  // Remove a value from the list.
    72  //
    73  // This function will panic with uncomparable types.
    74  //
    75  // Use RemoveIndex(index) instead.
    76  func (l *Singly[T]) Remove(v T) bool {
    77  	if l.len == 0 {
    78  		return false
    79  	}
    80  	var i = 0
    81  	for n := l.head; n != nil; n = n.next {
    82  		if any(n.value) == any(v) { // panic on comparison of uncomparable types.
    83  			l.remove(i, n)
    84  			return true
    85  		}
    86  		i++
    87  	}
    88  	return false
    89  }
    90  
    91  // Remove a value from the list at a given index.
    92  func (l *Singly[T]) RemoveIndex(i int) bool {
    93  	if i < 0 || i >= l.len {
    94  		return false
    95  	}
    96  
    97  	if i == 0 {
    98  		l.remove(i, l.head)
    99  		return true
   100  	}
   101  
   102  	var n *Node[T]
   103  	n = l.head
   104  	for j := 0; j < i; j++ {
   105  		n = n.next
   106  	}
   107  	if n != nil {
   108  		l.remove(i, n)
   109  		return true
   110  	}
   111  	return false
   112  }
   113  
   114  // Remove a value from the list if the predicate returns true.
   115  //
   116  // Returns the number of values removed.
   117  func (l *Singly[T]) RemoveIf(predicate func(T) bool) int {
   118  	var removed = 0
   119  	var i = 0
   120  	for n := l.head; n != nil; n = n.next {
   121  		if predicate(n.value) {
   122  			l.remove(i, n)
   123  			removed++
   124  		}
   125  		i++
   126  	}
   127  	return removed
   128  }
   129  
   130  // Returns the list as a slice.
   131  func (l *Singly[T]) ToSlice() []T {
   132  	if l.len == 0 {
   133  		return nil
   134  	}
   135  	var slice = make([]T, l.len)
   136  	var i = 0
   137  	for n := l.head; n != nil; n = n.next {
   138  		slice[i] = n.value
   139  		i++
   140  	}
   141  	return slice
   142  }
   143  
   144  // MarshalJSON implements the json.Marshaler interface.
   145  func (l *Singly[T]) MarshalJSON() ([]byte, error) {
   146  	return json.Marshal(l.ToSlice())
   147  }
   148  
   149  // UnmarshalJSON implements the json.Unmarshaler interface.
   150  func (l *Singly[T]) UnmarshalJSON(data []byte) error {
   151  	var slice []T
   152  	if err := json.Unmarshal(data, &slice); err != nil {
   153  		return err
   154  	}
   155  	for _, v := range slice {
   156  		l.Prepend(v)
   157  	}
   158  	return nil
   159  }
   160  
   161  func (l *Singly[T]) prepend(n *Node[T]) {
   162  	if l.head == nil {
   163  		l.head = n
   164  	} else {
   165  		var oldHead = l.head
   166  		l.head = n
   167  		l.head.next = oldHead
   168  	}
   169  	l.len++
   170  }
   171  
   172  // remove removes a node from the list.
   173  func (l *Singly[T]) remove(i int, n *Node[T]) {
   174  	if i == 0 {
   175  		l.head = n.next
   176  	} else {
   177  		if n.next != nil {
   178  			*n = *n.next
   179  		}
   180  	}
   181  	l.len--
   182  
   183  }