Skip to content

Instantly share code, notes, and snippets.

@mustafaturan
Last active July 7, 2019 02:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mustafaturan/9d2c1247203b12544b75b163b4ba7d11 to your computer and use it in GitHub Desktop.
Save mustafaturan/9d2c1247203b12544b75b163b4ba7d11 to your computer and use it in GitHub Desktop.
Stack Implementation With Go
package stack
type Stack struct {
*node
}
type node struct {
value string
next *node
}
// New inits a new stack
func New() *Stack {
return &Stack{}
}
// Push inserts an item to the stack
// Complexity: O(1)
func (s *Stack) Push(v string) {
s.node = &node{value: v, next: s.node}
}
// Pop removes the the last item from the stack
// Complexity: O(1)
func (s *Stack) Pop() string {
n := s.node
v := n.value
s.node = n.next
return v
}
// IsEmpty checks the stack's emptiness
// Complexity: O(1)
func (s *Stack) IsEmpty() bool {
return s.node == nil
}
// Size returns the size of the stack
// Complexity: O(n)
func (s *Stack) Size() uint {
if s.IsEmpty() {
return 0
}
size := uint(1)
t := s.node
for t.next != nil {
size++
t = t.next
}
return size
}
package stack
import (
"testing"
"reflect"
)
func TestNew(t *testing.T) {
s := New()
if reflect.TypeOf(*s) != reflect.TypeOf(Stack{}) {
t.Fatalf("invalid type")
}
}
func TestPush(t *testing.T) {
tests := []struct{
inputs []string
outputs []string
}{
{inputs: []string{"1", "2", "3"}, outputs: []string{"3", "2", "1"}},
}
for _, test := range tests {
s := New()
for _, val := range test.inputs {
s.Push(val)
}
for _, want := range test.outputs {
n := s.node
got := n.value
if got != want {
t.Fatalf("Push is not working for %v %s %s", test.inputs, got, want)
}
s.node = n.next
}
}
}
func TestPop(t *testing.T) {
tests := []struct{
stack *Stack
want []string
}{
{stack: &Stack{}, want: []string{}},
{stack: &Stack{node: &node{value: "1"}}, want: []string{"1"}},
{stack: &Stack{node: &node{value: "1", next: &node{value: "2"}}}, want: []string{"1", "2"}},
{stack: &Stack{node: &node{value: "1", next: &node{value: "2", next: &node{value: "3"}}}}, want: []string{"1", "2", "3"}},
}
for _, test := range tests {
s := test.stack
for _, want := range test.want {
got := s.Pop()
if got != want {
t.Fatalf("Pop is not working; want %s, but got %s", got, want)
}
}
}
}
func TestIsEmpty(t *testing.T) {
tests := []struct{
stack *Stack
want bool
}{
{stack: &Stack{}, want: true},
{stack: &Stack{node: &node{value: "1"}}, want: false},
{stack: &Stack{node: &node{value: "1", next: &node{value: "2"}}}, want: false},
{stack: &Stack{node: &node{value: "1", next: &node{value: "2", next: &node{value: "3"}}}}, want: false},
}
for _, test := range tests {
if got := test.stack.IsEmpty(); got != test.want {
t.Fatalf("no way")
}
}
}
func TestSize(t *testing.T) {
tests := []struct{
stack *Stack
want uint
}{
{stack: &Stack{}, want: 0},
{stack: &Stack{node: &node{value: "1"}}, want: 1},
{stack: &Stack{node: &node{value: "1", next: &node{value: "2"}}}, want: 2},
{stack: &Stack{node: &node{value: "1", next: &node{value: "2", next: &node{value: "3"}}}}, want: 3},
}
for _, test := range tests {
if got := test.stack.Size(); got != test.want {
t.Fatalf("no way")
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment