implement a generic stack

This commit is contained in:
Denis-Cosmin Nutiu 2024-11-27 23:20:19 +02:00
parent 768cbd9811
commit 79d1915d2d
6 changed files with 122 additions and 4 deletions

2
go.mod
View file

@ -1,3 +1,3 @@
module go-dsa module go-dsa
go 1.22 go 1.23

View file

@ -1,3 +1,10 @@
go 1.22.6 go 1.23
toolchain go1.23.3
use ./hash_set use ./hash_set
use (
.
./stack
)

View file

@ -7,8 +7,8 @@ What better way to learn a language and new concepts exists other than practicin
## Data Structures ## Data Structures
* Hash * Hash Set [Implementation](https://github.com/dnutiu/dsa-go/blob/master/hash_set/hash_set/hash_set.go) | [Tests](https://github.com/dnutiu/dsa-go/blob/master/hash_set/hash_set/hash_set_test.go)
Set [Implementation](https://github.com/dnutiu/dsa-go/blob/master/hash_set/hash_set/hash_set.go) | [Tests](https://github.com/dnutiu/dsa-go/blob/master/hash_set/hash_set/hash_set_test.go) * Generic Stack
### Other ### Other

10
stack/go.mod Normal file
View file

@ -0,0 +1,10 @@
module stack
go 1.23
require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/stretchr/testify v1.10.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

49
stack/stack.go Normal file
View file

@ -0,0 +1,49 @@
package main
import "errors"
// Stack is a simple stack implementation that holds uint16 data.
type Stack[T any] struct {
storage []T
stackSize uint32
}
// NewStack creates a new Stack instance.
func NewStack[T any]() *Stack[T] {
return &Stack[T]{
storage: make([]T, 0, 128),
stackSize: 0,
}
}
// Push pushes data into the stack.
func (s *Stack[T]) Push(data T) {
s.stackSize += 1
s.storage = append(s.storage, data)
}
// Pop pops an element from the stack.
func (s *Stack[T]) Pop() (T, error) {
var whatever T
if s.stackSize == 0 {
return whatever, errors.New("stack is empty")
}
data := s.storage[s.stackSize-1]
s.stackSize -= 1
return data, nil
}
// Peek peeks at the latest data stored on the stack.
func (s *Stack[T]) Peek() T {
return s.storage[s.stackSize-1]
}
// Size returns the current size of the stack.
func (s *Stack[T]) Size() uint32 {
return s.stackSize
}
// IsEmpty returns true if the stack is empty, false otherwise.
func (s *Stack[T]) IsEmpty() bool {
return s.stackSize == 0
}

52
stack/stack_test.go Normal file
View file

@ -0,0 +1,52 @@
package main
import (
"github.com/stretchr/testify/assert"
"testing"
)
func TestStack_NewStack(t *testing.T) {
// Given
stack := NewStack[string]()
// Then
assert.NotNil(t, stack)
}
func TestStack_BasicOperations(t *testing.T) {
// Given
stack := NewStack[uint16]()
// Then
stack.Push(uint16(2))
stack.Push(uint16(13))
assert.Equal(t, uint32(2), stack.Size())
assert.Equal(t, uint16(13), stack.Peek())
data, err := stack.Pop()
assert.Equal(t, uint16(13), data)
assert.Equal(t, uint32(1), stack.Size())
assert.NoError(t, err)
data, err = stack.Pop()
assert.Equal(t, uint16(2), data)
assert.Equal(t, uint32(0), stack.Size())
assert.NoError(t, err)
data, err = stack.Pop()
assert.Error(t, err)
}
func TestStack_IsEmpty(t *testing.T) {
// Given
stack := NewStack[int]()
// Then
assert.True(t, stack.IsEmpty())
stack.Push(1)
assert.False(t, stack.IsEmpty())
_, _ = stack.Pop()
assert.True(t, stack.IsEmpty())
}