Skip to content

Commit 19a8d8b

Browse files
committed
add arrayStack & linkedListStack
1 parent 86fa69f commit 19a8d8b

File tree

5 files changed

+372
-0
lines changed

5 files changed

+372
-0
lines changed

stacks/arrayStack.go

+90
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
// Copyright 2015 mint.zhao.chiu@gmail.com
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License"): you may
4+
// not use this file except in compliance with the License. You may obtain
5+
// a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11+
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12+
// License for the specific language governing permissions and limitations
13+
// under the License.
14+
package stacks
15+
16+
import (
17+
"fmt"
18+
"github.com/aiwuTech/container/lists"
19+
"strings"
20+
)
21+
22+
type ArrayStack struct {
23+
list *lists.ArrayList
24+
}
25+
26+
func NewArrayStack() *ArrayStack {
27+
return &ArrayStack{
28+
list: lists.NewArrayList(),
29+
}
30+
}
31+
32+
// Pushes a value onto the top of the stack
33+
func (stack *ArrayStack) Push(value interface{}) {
34+
stack.list.Add(value)
35+
}
36+
37+
// Pops (removes) top element on stack and returns it, or nil if stack is empty.
38+
// Second return parameter is true, unless the stack was empty and there was nothing to pop.
39+
func (stack *ArrayStack) Pop() (value interface{}, ok bool) {
40+
value, ok = stack.list.Get(stack.list.Len() - 1)
41+
stack.list.Remove(stack.list.Len() - 1)
42+
return
43+
}
44+
45+
// Returns top element on the stack without removing it, or nil if stack is empty.
46+
// Second return parameter is true, unless the stack was empty and there was nothing to peek.
47+
func (stack *ArrayStack) Peek() (value interface{}, ok bool) {
48+
return stack.list.Get(stack.list.Len() - 1)
49+
}
50+
51+
// Returns true if stack does not contain any elements.
52+
func (stack *ArrayStack) Empty() bool {
53+
return stack.list.Empty()
54+
}
55+
56+
// Returns number of elements within the stack.
57+
func (stack *ArrayStack) Len() int {
58+
return stack.list.Len()
59+
}
60+
61+
// Removes all elements from the stack.
62+
func (stack *ArrayStack) Clear() {
63+
stack.list.Clear()
64+
}
65+
66+
// Returns all elements in the stack (LIFO order).
67+
func (stack *ArrayStack) Elements() []interface{} {
68+
size := stack.list.Len()
69+
elements := make([]interface{}, size, size)
70+
for i := 1; i <= size; i++ {
71+
elements[size-i], _ = stack.list.Get(i - 1) // in reverse (LIFO)
72+
}
73+
return elements
74+
}
75+
76+
func (stack *ArrayStack) String() string {
77+
str := "ArrayStack{ "
78+
values := []string{}
79+
for _, value := range stack.list.Elements() {
80+
values = append(values, fmt.Sprintf("%v", value))
81+
}
82+
str += strings.Join(values, ", ")
83+
str += " }"
84+
return str
85+
}
86+
87+
// not important, just for interface{}
88+
func (stack *ArrayStack) Contains(elements ...interface{}) bool {
89+
return stack.list.Contains(elements...)
90+
}

stacks/arrayStock_test.go

+88
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
// Copyright 2015 mint.zhao.chiu@gmail.com
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License"): you may
4+
// not use this file except in compliance with the License. You may obtain
5+
// a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11+
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12+
// License for the specific language governing permissions and limitations
13+
// under the License.
14+
package stacks
15+
16+
import (
17+
"testing"
18+
)
19+
20+
func TestArrayStack(t *testing.T) {
21+
22+
stack := NewArrayStack()
23+
24+
if actualValue := stack.Empty(); actualValue != true {
25+
t.Errorf("Got %v expected %v", actualValue, true)
26+
}
27+
28+
// insertions
29+
stack.Push(1)
30+
stack.Push(2)
31+
stack.Push(3)
32+
33+
if actualValue := stack.Elements(); actualValue[0].(int) != 3 || actualValue[1].(int) != 2 || actualValue[2].(int) != 1 {
34+
t.Errorf("Got %v expected %v", actualValue, "[3,2,1]")
35+
}
36+
37+
if actualValue := stack.Empty(); actualValue != false {
38+
t.Errorf("Got %v expected %v", actualValue, false)
39+
}
40+
41+
if actualValue := stack.Len(); actualValue != 3 {
42+
t.Errorf("Got %v expected %v", actualValue, 3)
43+
}
44+
45+
if actualValue, ok := stack.Peek(); actualValue != 3 || !ok {
46+
t.Errorf("Got %v expected %v", actualValue, 3)
47+
}
48+
49+
stack.Pop()
50+
51+
if actualValue, ok := stack.Peek(); actualValue != 2 || !ok {
52+
t.Errorf("Got %v expected %v", actualValue, 2)
53+
}
54+
55+
if actualValue, ok := stack.Pop(); actualValue != 2 || !ok {
56+
t.Errorf("Got %v expected %v", actualValue, 2)
57+
}
58+
59+
if actualValue, ok := stack.Pop(); actualValue != 1 || !ok {
60+
t.Errorf("Got %v expected %v", actualValue, 1)
61+
}
62+
63+
if actualValue, ok := stack.Pop(); actualValue != nil || ok {
64+
t.Errorf("Got %v expected %v", actualValue, nil)
65+
}
66+
67+
if actualValue := stack.Empty(); actualValue != true {
68+
t.Errorf("Got %v expected %v", actualValue, true)
69+
}
70+
71+
if actualValue := stack.Elements(); len(actualValue) != 0 {
72+
t.Errorf("Got %v expected %v", actualValue, "[]")
73+
}
74+
75+
}
76+
77+
func BenchmarkArrayStack(b *testing.B) {
78+
for i := 0; i < b.N; i++ {
79+
stack := NewArrayStack()
80+
for n := 0; n < 1000; n++ {
81+
stack.Push(i)
82+
}
83+
for !stack.Empty() {
84+
stack.Pop()
85+
}
86+
}
87+
88+
}

stacks/linkedListStack.go

+86
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
// Copyright 2015 mint.zhao.chiu@gmail.com
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License"): you may
4+
// not use this file except in compliance with the License. You may obtain
5+
// a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11+
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12+
// License for the specific language governing permissions and limitations
13+
// under the License.
14+
package stacks
15+
16+
import (
17+
"fmt"
18+
"github.com/aiwuTech/container/lists"
19+
"strings"
20+
)
21+
22+
type LinkedListStack struct {
23+
list *lists.SinglyLinkedList
24+
}
25+
26+
// Instantiates a new empty stack
27+
func NewLinkedListStack() *LinkedListStack {
28+
return &LinkedListStack{
29+
list: lists.NewSinglyLinkedList(),
30+
}
31+
}
32+
33+
// Pushes a value onto the top of the stack
34+
func (stack *LinkedListStack) Push(value interface{}) {
35+
stack.list.Prepend(value)
36+
}
37+
38+
// Pops (removes) top element on stack and returns it, or nil if stack is empty.
39+
// Second return parameter is true, unless the stack was empty and there was nothing to pop.
40+
func (stack *LinkedListStack) Pop() (value interface{}, ok bool) {
41+
value, ok = stack.list.Get(0)
42+
stack.list.Remove(0)
43+
return
44+
}
45+
46+
// Returns top element on the stack without removing it, or nil if stack is empty.
47+
// Second return parameter is true, unless the stack was empty and there was nothing to peek.
48+
func (stack *LinkedListStack) Peek() (value interface{}, ok bool) {
49+
return stack.list.Get(0)
50+
}
51+
52+
// Returns true if stack does not contain any elements.
53+
func (stack *LinkedListStack) Empty() bool {
54+
return stack.list.Empty()
55+
}
56+
57+
// Returns number of elements within the stack.
58+
func (stack *LinkedListStack) Len() int {
59+
return stack.list.Len()
60+
}
61+
62+
// Removes all elements from the stack.
63+
func (stack *LinkedListStack) Clear() {
64+
stack.list.Clear()
65+
}
66+
67+
// Returns all elements in the stack (LIFO order).
68+
func (stack *LinkedListStack) Elements() []interface{} {
69+
return stack.list.Elements()
70+
}
71+
72+
func (stack *LinkedListStack) String() string {
73+
str := "LinkedListStack{ "
74+
values := []string{}
75+
for _, value := range stack.list.Elements() {
76+
values = append(values, fmt.Sprintf("%v", value))
77+
}
78+
str += strings.Join(values, ", ")
79+
str += " }"
80+
return str
81+
}
82+
83+
// not important, just for interface{}
84+
func (stack *LinkedListStack) Contains(elements ...interface{}) bool {
85+
return stack.list.Contains(elements...)
86+
}

stacks/linkedListStack_test.go

+85
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
// Copyright 2015 mint.zhao.chiu@gmail.com
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License"): you may
4+
// not use this file except in compliance with the License. You may obtain
5+
// a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11+
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12+
// License for the specific language governing permissions and limitations
13+
// under the License.
14+
package stacks
15+
16+
import "testing"
17+
18+
func TestLinkedListStack(t *testing.T) {
19+
20+
stack := NewLinkedListStack()
21+
22+
if actualValue := stack.Empty(); actualValue != true {
23+
t.Errorf("Got %v expected %v", actualValue, true)
24+
}
25+
26+
// insertions
27+
stack.Push(1)
28+
stack.Push(2)
29+
stack.Push(3)
30+
31+
if actualValue := stack.Elements(); actualValue[0].(int) != 3 || actualValue[1].(int) != 2 || actualValue[2].(int) != 1 {
32+
t.Errorf("Got %v expected %v", actualValue, "[3,2,1]")
33+
}
34+
35+
if actualValue := stack.Empty(); actualValue != false {
36+
t.Errorf("Got %v expected %v", actualValue, false)
37+
}
38+
39+
if actualValue := stack.Len(); actualValue != 3 {
40+
t.Errorf("Got %v expected %v", actualValue, 3)
41+
}
42+
43+
if actualValue, ok := stack.Peek(); actualValue != 3 || !ok {
44+
t.Errorf("Got %v expected %v", actualValue, 3)
45+
}
46+
47+
stack.Pop()
48+
49+
if actualValue, ok := stack.Peek(); actualValue != 2 || !ok {
50+
t.Errorf("Got %v expected %v", actualValue, 2)
51+
}
52+
53+
if actualValue, ok := stack.Pop(); actualValue != 2 || !ok {
54+
t.Errorf("Got %v expected %v", actualValue, 2)
55+
}
56+
57+
if actualValue, ok := stack.Pop(); actualValue != 1 || !ok {
58+
t.Errorf("Got %v expected %v", actualValue, 1)
59+
}
60+
61+
if actualValue, ok := stack.Pop(); actualValue != nil || ok {
62+
t.Errorf("Got %v expected %v", actualValue, nil)
63+
}
64+
65+
if actualValue := stack.Empty(); actualValue != true {
66+
t.Errorf("Got %v expected %v", actualValue, true)
67+
}
68+
69+
if actualValue := stack.Elements(); len(actualValue) != 0 {
70+
t.Errorf("Got %v expected %v", actualValue, "[]")
71+
}
72+
73+
}
74+
75+
func BenchmarkLinkedListStack(b *testing.B) {
76+
for i := 0; i < b.N; i++ {
77+
stack := NewLinkedListStack()
78+
for n := 0; n < 1000; n++ {
79+
stack.Push(i)
80+
}
81+
for !stack.Empty() {
82+
stack.Pop()
83+
}
84+
}
85+
}

stacks/stack.go

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Copyright 2015 mint.zhao.chiu@gmail.com
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License"): you may
4+
// not use this file except in compliance with the License. You may obtain
5+
// a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11+
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12+
// License for the specific language governing permissions and limitations
13+
// under the License.
14+
package stacks
15+
16+
import "github.com/aiwuTech/container"
17+
18+
type StackInterface interface {
19+
Push(value interface{})
20+
Pop() (value interface{}, ok bool)
21+
Peek() (value interface{}, ok bool)
22+
container.ContainerInterface
23+
}

0 commit comments

Comments
 (0)