ArrayList addition (inc. test, example and documentation)

pull/1/head
emirpasic 9 years ago
parent fdbea4bd27
commit 28f559cc09

@ -152,6 +152,7 @@ All stacks implement the stack interface with the following methods:
Empty() bool
Size() int
Clear()
Values() []interface{}
```
####LinkedListStack
@ -169,6 +170,7 @@ func main() {
stack := lls.New() // empty
stack.Push(1) // 1
stack.Push(2) // 1, 2
stack.Values() // 2, 1 (LIFO order)
_, _ = stack.Peek() // 2,true
_, _ = stack.Pop() // 2, true
_, _ = stack.Pop() // 1, true
@ -183,7 +185,7 @@ func main() {
####ArrayStack
This stack structure is based on a array.
This stack structure is back by ArrayList.
All operations are guaranted constant time performance.
@ -196,6 +198,7 @@ func main() {
stack := arraystack.New() // empty
stack.Push(1) // 1
stack.Push(2) // 1, 2
stack.Values() // 2, 1 (LIFO order)
_, _ = stack.Peek() // 2,true
_, _ = stack.Pop() // 2, true
_, _ = stack.Pop() // 1, true

@ -32,6 +32,7 @@ func ArrayStackExample() {
stack := arraystack.New() // empty
stack.Push(1) // 1
stack.Push(2) // 1, 2
stack.Values() // 2, 1 (LIFO order)
_, _ = stack.Peek() // 2,true
_, _ = stack.Pop() // 2, true
_, _ = stack.Pop() // 1, true

@ -32,6 +32,7 @@ func LinkedListStackExample() {
stack := lls.New() // empty
stack.Push(1) // 1
stack.Push(2) // 1, 2
stack.Values() // 2, 1 (LIFO order)
_, _ = stack.Peek() // 2,true
_, _ = stack.Pop() // 2, true
_, _ = stack.Pop() // 1, true

@ -24,7 +24,7 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// Implementation of stack using a slice.
// Implementation of stack backed by ArrayList.
// Structure is not thread safe.
// References: http://en.wikipedia.org/wiki/Stack_%28abstract_data_type%29
@ -32,6 +32,7 @@ package arraystack
import (
"fmt"
"github.com/emirpasic/gods/lists/arraylist"
"github.com/emirpasic/gods/stacks"
"strings"
)
@ -41,64 +42,54 @@ func assertInterfaceImplementation() {
}
type Stack struct {
elements []interface{}
top int
list *arraylist.List
}
// Instantiates a new empty stack
func New() *Stack {
return &Stack{top: -1}
return &Stack{list: arraylist.New()}
}
// Pushes a value onto the top of the stack
func (stack *Stack) Push(value interface{}) {
// Increase when capacity is reached by a factor of 1.5 and add one so it grows when size is zero
if stack.top+1 >= cap(stack.elements) {
currentSize := len(stack.elements)
sizeIncrease := int(1.5*float32(currentSize) + 1.0)
newSize := currentSize + sizeIncrease
newItems := make([]interface{}, newSize, newSize)
copy(newItems, stack.elements)
stack.elements = newItems
}
stack.top += 1
stack.elements[stack.top] = value
stack.list.Add(value)
}
// Pops (removes) top element on stack and returns it, or nil if stack is empty.
// Second return parameter is true, unless the stack was empty and there was nothing to pop.
func (stack *Stack) Pop() (value interface{}, ok bool) {
if stack.top >= 0 {
value, ok = stack.elements[stack.top], true
stack.top -= 1
return
}
return nil, false
return stack.list.Get(stack.list.Size() - 1)
}
// Returns top element on the stack without removing it, or nil if stack is empty.
// Second return parameter is true, unless the stack was empty and there was nothing to peek.
func (stack *Stack) Peek() (value interface{}, ok bool) {
if stack.top >= 0 {
return stack.elements[stack.top], true
}
return nil, false
return stack.list.Get(stack.list.Size() - 1)
}
// Returns true if stack does not contain any elements.
func (stack *Stack) Empty() bool {
return stack.Size() == 0
return stack.list.Empty()
}
// Returns number of elements within the stack.
func (stack *Stack) Size() int {
return stack.top + 1
return stack.list.Size()
}
// Removes all elements from the stack.
func (stack *Stack) Clear() {
stack.top = -1
stack.elements = []interface{}{}
return stack.list.Clear()
}
// Returns all elements in the stack (LIFO order).
func (stack *Stack) Values() []interface{} {
size := stack.list.Size()
elements := make([]interface{}, size, size)
for i := size - 1; i >= 0; i-- { // in reverse
elements[i] = stack.list.Get(i)
}
return elements
}
func (stack *Stack) String() string {

@ -27,6 +27,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package arraystack
import (
"github.com/emirpasic/gods/utils"
"testing"
)
@ -43,6 +44,10 @@ func TestArrayStack(t *testing.T) {
stack.Push(2)
stack.Push(3)
if actualValue := stack.Values(); !utils.IdenticalSlices(actualValue, []interface{}{3, 2, 1}) {
t.Errorf("Got %v expected %v", actualValue, []interface{}{3, 2, 1})
}
if actualValue := stack.Empty(); actualValue != false {
t.Errorf("Got %v expected %v", actualValue, false)
}
@ -77,6 +82,10 @@ func TestArrayStack(t *testing.T) {
t.Errorf("Got %v expected %v", actualValue, true)
}
if actualValue := stack.Values(); !utils.IdenticalSlices(actualValue, []interface{}{}) {
t.Errorf("Got %v expected %v", actualValue, []interface{}{})
}
}
func BenchmarkArrayStack(b *testing.B) {

@ -98,6 +98,19 @@ func (stack *Stack) Clear() {
stack.size = 0
}
// Returns all elements in the stack (LIFO order).
func (stack *Stack) Values() []interface{} {
size := stack.list.Size()
elements := make([]interface{}, size, size)
element := stack.top
for index := 0; element != nil; index++ {
elements[index] = element
element = element.next
}
return elements
}
func (stack *Stack) String() string {
str := "LinkedListStack\n"
element := stack.top

@ -27,6 +27,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package linkedliststack
import (
"github.com/emirpasic/gods/utils"
"testing"
)
@ -43,6 +44,10 @@ func TestLinkedListStack(t *testing.T) {
stack.Push(2)
stack.Push(3)
if actualValue := stack.Values(); !utils.IdenticalSlices(actualValue, []interface{}{3, 2, 1}) {
t.Errorf("Got %v expected %v", actualValue, []interface{}{3, 2, 1})
}
if actualValue := stack.Empty(); actualValue != false {
t.Errorf("Got %v expected %v", actualValue, false)
}
@ -77,6 +82,10 @@ func TestLinkedListStack(t *testing.T) {
t.Errorf("Got %v expected %v", actualValue, true)
}
if actualValue := stack.Values(); !utils.IdenticalSlices(actualValue, []interface{}{}) {
t.Errorf("Got %v expected %v", actualValue, []interface{}{})
}
}
func BenchmarkLinkedListStack(b *testing.B) {

@ -33,4 +33,5 @@ type Interface interface {
Empty() bool
Size() int
Clear()
Values() []interface{}
}

@ -0,0 +1,14 @@
package utils
// order and elements in the two slices have to match
func IdenticalSlices(s1 []interface{}, s2 []interface{}) bool {
if len(s1) != len(s2) {
return false
}
for i := 0; i < len(s1); i++ {
if s1[i] != s2[i] {
return false
}
}
return true
}
Loading…
Cancel
Save