From eb59d02a0898fe67721c4babf6f2424192abede7 Mon Sep 17 00:00:00 2001 From: dudaodong Date: Fri, 4 Feb 2022 19:35:06 +0800 Subject: [PATCH] feat: add stackarray.go implements stack with array --- datastructure/node.go | 13 +++++- datastructure/stackarray.go | 62 +++++++++++++++++++++++++ datastructure/stackarray_test.go | 77 ++++++++++++++++++++++++++++++++ 3 files changed, 151 insertions(+), 1 deletion(-) create mode 100644 datastructure/stackarray.go create mode 100644 datastructure/stackarray_test.go diff --git a/datastructure/node.go b/datastructure/node.go index bf89e31..db3b5d4 100644 --- a/datastructure/node.go +++ b/datastructure/node.go @@ -1,13 +1,24 @@ package datastructure -// LinkNode is a linkedlist node, which have a value and Pre points to previous node, Next points to a next node of the link. +// LinkNode is a linkedlist node, which have a Value and Pre points to previous node, Next points to a next node of the link. type LinkNode[T any] struct { Value T Pre *LinkNode[T] Next *LinkNode[T] } +// NewLinkNode return a LinkNode pointer func NewLinkNode[T any](value T) *LinkNode[T] { return &LinkNode[T]{value, nil, nil} } +// StackNode is a node in stack, which have a Value and Pre points to previous node in the stack. +type StackNode[T any] struct { + Value T + Pre *StackNode[T] +} + +// NewStackNode return a StackNode pointer +func NewStackNode[T any](value T) *StackNode[T] { + return &StackNode[T]{value, nil} +} diff --git a/datastructure/stackarray.go b/datastructure/stackarray.go new file mode 100644 index 0000000..a4efde0 --- /dev/null +++ b/datastructure/stackarray.go @@ -0,0 +1,62 @@ +package datastructure + +import "errors" + +// StackArray is a linear table, implemented with slice +type StackArray[T any] struct { + data []T + length int +} + +// NewStackArray return a empty StackArray pointer +func NewStackArray[T any]() *StackArray[T] { + return &StackArray[T]{data: []T{}, length: 0} +} + +// Data return stack data +func (s *StackArray[T]) Data() []T { + return s.data +} + +// Length return length of stack data +func (s *StackArray[T]) Length() int { + return s.length +} + +// IsEmpty checks if stack is empty or not +func (s *StackArray[T]) IsEmpty() bool { + return s.length == 0 +} + +// Push element into stack +func (s *StackArray[T]) Push(value T) { + s.data = append([]T{value}, s.data...) + s.length++ +} + +// Pop delete the top element of stack then return it, if stack is empty, return nil and error +func (s *StackArray[T]) Pop() (*T, error) { + if s.IsEmpty() { + return nil, errors.New("stack is empty") + } + + topItem := s.data[0] + s.data = s.data[1:] + s.length-- + + return &topItem, nil +} + +// Peak return the top element of stack then return it +func (s *StackArray[T]) Peak() (*T, error) { + if s.IsEmpty() { + return nil, errors.New("stack is empty") + } + return &s.data[0], nil +} + +// EmptyStack clear the stack data +func (s *StackArray[T]) EmptyStack() { + s.data = []T{} + s.length = 0 +} diff --git a/datastructure/stackarray_test.go b/datastructure/stackarray_test.go new file mode 100644 index 0000000..6de2bdc --- /dev/null +++ b/datastructure/stackarray_test.go @@ -0,0 +1,77 @@ +package datastructure + +import ( + "testing" + + "github.com/duke-git/lancet/internal" +) + +func TestStackArray_Push(t *testing.T) { + assert := internal.NewAssert(t, "TestStackArray_Push") + + stack := NewStackArray[int]() + stack.Push(1) + stack.Push(2) + stack.Push(3) + + expected := []int{3, 2, 1} + values := stack.Data() + length := stack.Length() + + assert.Equal(expected, values) + assert.Equal(3, length) +} + +func TestStackArray_Pop(t *testing.T) { + assert := internal.NewAssert(t, "TestStackArray_Pop") + + stack := NewStackArray[int]() + topItem, err := stack.Pop() + assert.IsNotNil(err) + + stack.Push(1) + stack.Push(2) + stack.Push(3) + + topItem, err = stack.Pop() + assert.IsNil(err) + assert.Equal(3, *topItem) + + expected := []int{2, 1} + assert.Equal(expected, stack.Data()) +} + +func TestStackArray_Peak(t *testing.T) { + assert := internal.NewAssert(t, "TestStackArray_Peak") + + stack := NewStackArray[int]() + topItem, err := stack.Peak() + assert.IsNotNil(err) + + stack.Push(1) + stack.Push(2) + stack.Push(3) + + topItem, err = stack.Peak() + assert.IsNil(err) + assert.Equal(3, *topItem) + + expected := []int{3, 2, 1} + assert.Equal(expected, stack.Data()) +} + +func TestStackArray_Empty(t *testing.T) { + assert := internal.NewAssert(t, "TestStackArray_Empty") + + stack := NewStackArray[int]() + assert.Equal(true, stack.IsEmpty()) + assert.Equal(0, stack.Length()) + + stack.Push(1) + assert.Equal(false, stack.IsEmpty()) + assert.Equal(1, stack.Length()) + + stack.EmptyStack() + assert.Equal(true, stack.IsEmpty()) + assert.Equal(0, stack.Length()) +}