mirror of
https://github.com/duke-git/lancet.git
synced 2026-02-15 18:22:27 +08:00
rename: rename StackArray -> ArrayStack, StackLink -> LinkedStack
This commit is contained in:
62
datastructure/arraystack.go
Normal file
62
datastructure/arraystack.go
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
package datastructure
|
||||||
|
|
||||||
|
import "errors"
|
||||||
|
|
||||||
|
// ArrayStack implements stack with slice
|
||||||
|
type ArrayStack[T any] struct {
|
||||||
|
data []T
|
||||||
|
length int
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewArrayStack return a empty ArrayStack pointer
|
||||||
|
func NewArrayStack[T any]() *ArrayStack[T] {
|
||||||
|
return &ArrayStack[T]{data: []T{}, length: 0}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Data return stack data
|
||||||
|
func (s *ArrayStack[T]) Data() []T {
|
||||||
|
return s.data
|
||||||
|
}
|
||||||
|
|
||||||
|
// Length return length of stack data
|
||||||
|
func (s *ArrayStack[T]) Length() int {
|
||||||
|
return s.length
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsEmpty checks if stack is empty or not
|
||||||
|
func (s *ArrayStack[T]) IsEmpty() bool {
|
||||||
|
return s.length == 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// Push element into stack
|
||||||
|
func (s *ArrayStack[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 *ArrayStack[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 *ArrayStack[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 *ArrayStack[T]) EmptyStack() {
|
||||||
|
s.data = []T{}
|
||||||
|
s.length = 0
|
||||||
|
}
|
||||||
77
datastructure/arraystack_test.go
Normal file
77
datastructure/arraystack_test.go
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
package datastructure
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/duke-git/lancet/internal"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestArrayStack_Push(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestArrayStack_Push")
|
||||||
|
|
||||||
|
stack := NewArrayStack[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 TestArrayStack_Pop(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestArrayStack_Pop")
|
||||||
|
|
||||||
|
stack := NewArrayStack[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 TestArrayStack_Peak(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestArrayStack_Peak")
|
||||||
|
|
||||||
|
stack := NewArrayStack[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 TestArrayStack_Empty(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestArrayStack_Empty")
|
||||||
|
|
||||||
|
stack := NewArrayStack[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())
|
||||||
|
}
|
||||||
92
datastructure/linkedstack.go
Normal file
92
datastructure/linkedstack.go
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
package datastructure
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
// LinkedStack implements stack with link list
|
||||||
|
type LinkedStack[T any] struct {
|
||||||
|
top *StackNode[T]
|
||||||
|
length int
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewLinkedStack return a empty LinkedStack pointer
|
||||||
|
func NewLinkedStack[T any]() *LinkedStack[T] {
|
||||||
|
return &LinkedStack[T]{top: nil, length: 0}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Data return stack data
|
||||||
|
func (s *LinkedStack[T]) Data() []T {
|
||||||
|
res := []T{}
|
||||||
|
current := s.top
|
||||||
|
|
||||||
|
for current != nil {
|
||||||
|
res = append(res, current.Value)
|
||||||
|
current = current.Next
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
// Length return length of stack data
|
||||||
|
func (s *LinkedStack[T]) Length() int {
|
||||||
|
return s.length
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsEmpty checks if stack is empty or not
|
||||||
|
func (s *LinkedStack[T]) IsEmpty() bool {
|
||||||
|
return s.length == 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// Push element into stack
|
||||||
|
func (s *LinkedStack[T]) Push(value T) {
|
||||||
|
newNode := NewStackNode(value)
|
||||||
|
top := s.top
|
||||||
|
if top == nil {
|
||||||
|
s.top = newNode
|
||||||
|
} else {
|
||||||
|
newNode.Next = top
|
||||||
|
s.top = newNode
|
||||||
|
}
|
||||||
|
|
||||||
|
s.length++
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pop delete the top element of stack then return it, if stack is empty, return nil and error
|
||||||
|
func (s *LinkedStack[T]) Pop() (*T, error) {
|
||||||
|
if s.IsEmpty() {
|
||||||
|
return nil, errors.New("stack is empty")
|
||||||
|
}
|
||||||
|
|
||||||
|
top := s.top
|
||||||
|
s.top = s.top.Next
|
||||||
|
s.length--
|
||||||
|
|
||||||
|
return &top.Value, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Peak return the top element of stack then return it
|
||||||
|
func (s *LinkedStack[T]) Peak() (*T, error) {
|
||||||
|
if s.IsEmpty() {
|
||||||
|
return nil, errors.New("stack is empty")
|
||||||
|
}
|
||||||
|
return &s.top.Value, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// EmptyStack clear the stack data
|
||||||
|
func (s *LinkedStack[T]) EmptyStack() {
|
||||||
|
s.top = nil
|
||||||
|
s.length = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print all nodes info of stack link
|
||||||
|
func (s *LinkedStack[T]) Print() {
|
||||||
|
current := s.top
|
||||||
|
info := "[ "
|
||||||
|
for current != nil {
|
||||||
|
info += fmt.Sprintf("%+v, ", current)
|
||||||
|
current = current.Next
|
||||||
|
}
|
||||||
|
info += " ]"
|
||||||
|
fmt.Println(info)
|
||||||
|
}
|
||||||
80
datastructure/linkedstack_test.go
Normal file
80
datastructure/linkedstack_test.go
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
package datastructure
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/duke-git/lancet/internal"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestLinkedStack_Push(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestLinkedStack_Push")
|
||||||
|
|
||||||
|
stack := NewLinkedStack[int]()
|
||||||
|
stack.Push(1)
|
||||||
|
stack.Push(2)
|
||||||
|
stack.Push(3)
|
||||||
|
|
||||||
|
stack.Print()
|
||||||
|
|
||||||
|
expected := []int{3, 2, 1}
|
||||||
|
values := stack.Data()
|
||||||
|
length := stack.Length()
|
||||||
|
|
||||||
|
assert.Equal(expected, values)
|
||||||
|
assert.Equal(3, length)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestLinkedStack_Pop(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestLinkedStack_Pop")
|
||||||
|
|
||||||
|
stack := NewLinkedStack[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}
|
||||||
|
stack.Print()
|
||||||
|
assert.Equal(expected, stack.Data())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestLinkedStack_Peak(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestLinkedStack_Peak")
|
||||||
|
|
||||||
|
stack := NewLinkedStack[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 TestLinkedStack_Empty(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestLinkedStack_Empty")
|
||||||
|
|
||||||
|
stack := NewLinkedStack[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())
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user