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 }