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

     1  // Package linkedliststack implements a stack backed by a singly-linked list.
     2  //
     3  // Structure is not thread safe.
     4  //
     5  // Reference:https://en.wikipedia.org/wiki/Stack_%28abstract_data_type%29#Linked_list
     6  package linkedliststack
     7  
     8  import (
     9  	"fmt"
    10  	"strings"
    11  
    12  	"github.com/songzhibin97/go-baseutils/structure/lists/singlylinkedlist"
    13  	"github.com/songzhibin97/go-baseutils/structure/stacks"
    14  )
    15  
    16  // Assert Stack implementation
    17  var _ stacks.Stack[any] = (*Stack[any])(nil)
    18  
    19  // Stack holds elements in a singly-linked-list
    20  type Stack[E any] struct {
    21  	list *singlylinkedlist.List[E]
    22  }
    23  
    24  // New nnstantiates a new empty stack
    25  func New[E any]() *Stack[E] {
    26  	return &Stack[E]{list: &singlylinkedlist.List[E]{}}
    27  }
    28  
    29  // Push adds a value onto the top of the stack
    30  func (stack *Stack[E]) Push(value E) {
    31  	stack.list.Prepend(value)
    32  }
    33  
    34  // Pop removes top element on stack and returns it, or nil if stack is empty.
    35  // Second return parameter is true, unless the stack was empty and there was nothing to pop.
    36  func (stack *Stack[E]) Pop() (value E, ok bool) {
    37  	value, ok = stack.list.Get(0)
    38  	stack.list.Remove(0)
    39  	return
    40  }
    41  
    42  // Peek returns top element on the stack without removing it, or nil if stack is empty.
    43  // Second return parameter is true, unless the stack was empty and there was nothing to peek.
    44  func (stack *Stack[E]) Peek() (value E, ok bool) {
    45  	return stack.list.Get(0)
    46  }
    47  
    48  // Empty returns true if stack does not contain any elements.
    49  func (stack *Stack[E]) Empty() bool {
    50  	return stack.list.Empty()
    51  }
    52  
    53  // Size returns number of elements within the stack.
    54  func (stack *Stack[E]) Size() int {
    55  	return stack.list.Size()
    56  }
    57  
    58  // Clear removes all elements from the stack.
    59  func (stack *Stack[E]) Clear() {
    60  	stack.list.Clear()
    61  }
    62  
    63  // Values returns all elements in the stack (LIFO order).
    64  func (stack *Stack[E]) Values() []E {
    65  	return stack.list.Values()
    66  }
    67  
    68  // String returns a string representation of container
    69  func (stack *Stack[E]) String() string {
    70  	b := strings.Builder{}
    71  	b.WriteString("LinkedListStack\n")
    72  	for index, value := range stack.list.Values() {
    73  		b.WriteString(fmt.Sprintf("(index:%d value:%v) ", index, value))
    74  	}
    75  	return b.String()
    76  }
    77  
    78  // Check that the index is within bounds of the list
    79  func (stack *Stack[E]) withinRange(index int) bool {
    80  	return index >= 0 && index < stack.list.Size()
    81  }
    82  
    83  // UnmarshalJSON @implements json.Unmarshaler
    84  func (stack *Stack[E]) UnmarshalJSON(bytes []byte) error {
    85  	return stack.list.UnmarshalJSON(bytes)
    86  }
    87  
    88  // MarshalJSON @implements json.Marshaler
    89  func (stack *Stack[E]) MarshalJSON() ([]byte, error) {
    90  	return stack.list.MarshalJSON()
    91  }