Added constructor function on linked list and stack data structures

This commit is contained in:
Fabio Scotto di Santolo
2023-01-06 11:41:41 +01:00
parent 4b25a6b1c6
commit ac20be21e4
4 changed files with 95 additions and 76 deletions

View File

@@ -70,6 +70,14 @@ type LinkedList[E any] struct {
size int
}
func NewLinkedList[E any](items ...E) *LinkedList[E] {
lst := &LinkedList[E]{}
for _, item := range items {
lst.PushBack(item)
}
return lst
}
func (l *LinkedList[E]) Iterator() Iterator[E] {
if l.Empty() {
return &emptyListIterator[E]{}

View File

@@ -10,9 +10,9 @@ func TestLinkedList_Empty(t *testing.T) {
list *LinkedList[int]
want bool
}{
{description: "no items in list", list: newList(), want: true},
{description: "one item in list", list: newList(1), want: false},
{description: "more items in list", list: newList(1, 2, 3), want: false},
{description: "no items in list", list: NewLinkedList[int](), want: true},
{description: "one item in list", list: NewLinkedList(1), want: false},
{description: "more items in list", list: NewLinkedList(1, 2, 3), want: false},
}
for _, tt := range useCases {
@@ -29,9 +29,9 @@ func TestLinkedList_Size(t *testing.T) {
list *LinkedList[int]
want int
}{
{description: "no items in list", list: newList(), want: 0},
{description: "one item in list", list: newList(1), want: 1},
{description: "more items in list", list: newList(1, 2, 3), want: 3},
{description: "no items in list", list: NewLinkedList[int](), want: 0},
{description: "one item in list", list: NewLinkedList(1), want: 1},
{description: "more items in list", list: NewLinkedList(1, 2, 3), want: 3},
}
for _, tt := range useCases {
@@ -50,13 +50,13 @@ func TestLinkedList_GetAt(t *testing.T) {
err error
want int
}{
{description: "get first item", list: newList(1, 2, 3), pos: 0, want: 1, err: nil},
{description: "get middle item", list: newList(1, 2, 3), pos: 1, want: 2, err: nil},
{description: "get last item", list: newList(1, 2, 3), pos: 2, want: 3, err: nil},
{description: "get last item", list: newList(1, 2, 3), pos: 2, want: 3, err: nil},
{description: "no items in list return zero value of the type", list: newList(), pos: 0, want: 0, err: ErrEmptyList},
{description: "get item with negative position", list: newList(1, 2, 3), pos: -1, want: 0, err: ErrPositionNegative},
{description: "get item with index out of bound", list: newList(1, 2, 3), pos: 4, want: 0, err: ErrIndexOutOfBound{4, 3}},
{description: "get first item", list: NewLinkedList(1, 2, 3), pos: 0, want: 1, err: nil},
{description: "get middle item", list: NewLinkedList(1, 2, 3), pos: 1, want: 2, err: nil},
{description: "get last item", list: NewLinkedList(1, 2, 3), pos: 2, want: 3, err: nil},
{description: "get last item", list: NewLinkedList(1, 2, 3), pos: 2, want: 3, err: nil},
{description: "no items in list return zero value of the type", list: NewLinkedList[int](), pos: 0, want: 0, err: ErrEmptyList},
{description: "get item with negative position", list: NewLinkedList(1, 2, 3), pos: -1, want: 0, err: ErrPositionNegative},
{description: "get item with index out of bound", list: NewLinkedList(1, 2, 3), pos: 4, want: 0, err: ErrIndexOutOfBound{4, 3}},
}
for _, tt := range useCases {
@@ -74,9 +74,9 @@ func TestLinkedList_Back(t *testing.T) {
err error
want int
}{
{description: "no items in list return zero value of the type", list: newList(), want: 0, err: ErrEmptyList},
{description: "singleton list return first element", list: newList(1), want: 1},
{description: "get last item", list: newList(1, 2, 3), want: 3},
{description: "no items in list return zero value of the type", list: NewLinkedList[int](), want: 0, err: ErrEmptyList},
{description: "singleton list return first element", list: NewLinkedList(1), want: 1},
{description: "get last item", list: NewLinkedList(1, 2, 3), want: 3},
}
for _, tt := range useCases {
@@ -94,9 +94,9 @@ func TestLinkedList_Front(t *testing.T) {
err error
want int
}{
{description: "no items in list return zero value of the type", list: newList(), want: 0, err: ErrEmptyList},
{description: "singleton list return first element", list: newList(1), want: 1},
{description: "get first item", list: newList(1, 2, 3), want: 1},
{description: "no items in list return zero value of the type", list: NewLinkedList[int](), want: 0, err: ErrEmptyList},
{description: "singleton list return first element", list: NewLinkedList(1), want: 1},
{description: "get first item", list: NewLinkedList(1, 2, 3), want: 1},
}
for _, tt := range useCases {
@@ -116,23 +116,23 @@ func TestLinkedList_PushAt(t *testing.T) {
item int
}{
{description: "add item in first position in empty list",
original: newList(),
modified: newList(1),
original: NewLinkedList[int](),
modified: NewLinkedList(1),
pos: 0,
item: 1},
{description: "add item in first position in full list",
original: newList(1, 2, 3),
modified: newList(0, 1, 2, 3),
original: NewLinkedList(1, 2, 3),
modified: NewLinkedList(0, 1, 2, 3),
pos: 0,
item: 0},
{description: "add item in middle position in full list",
original: newList(1, 2, 3),
modified: newList(1, 2, 0, 3),
original: NewLinkedList(1, 2, 3),
modified: NewLinkedList(1, 2, 0, 3),
pos: 2,
item: 0},
{description: "add item in last position in full list",
original: newList(1, 2, 3),
modified: newList(1, 2, 3, 0),
original: NewLinkedList(1, 2, 3),
modified: NewLinkedList(1, 2, 3, 0),
pos: 3,
item: 0},
}
@@ -154,16 +154,16 @@ func TestLinkedList_PushBack(t *testing.T) {
item int
}{
{description: "add item in first position in empty list",
original: newList(),
modified: newList(1),
original: NewLinkedList[int](),
modified: NewLinkedList(1),
item: 1},
{description: "add item in singleton list",
original: newList(1),
modified: newList(1, 0),
original: NewLinkedList(1),
modified: NewLinkedList(1, 0),
item: 0},
{description: "add item in full list",
original: newList(1, 2, 3),
modified: newList(1, 2, 3, 0),
original: NewLinkedList(1, 2, 3),
modified: NewLinkedList(1, 2, 3, 0),
item: 0},
}
@@ -184,16 +184,16 @@ func TestLinkedList_PushFront(t *testing.T) {
item int
}{
{description: "add item in first position in empty list",
original: newList(),
modified: newList(1),
original: NewLinkedList[int](),
modified: NewLinkedList(1),
item: 1},
{description: "add item in singleton list",
original: newList(1),
modified: newList(0, 1),
original: NewLinkedList(1),
modified: NewLinkedList(0, 1),
item: 0},
{description: "add item in full list",
original: newList(1, 2, 3),
modified: newList(0, 1, 2, 3),
original: NewLinkedList(1, 2, 3),
modified: NewLinkedList(0, 1, 2, 3),
item: 0},
}
@@ -214,33 +214,33 @@ func TestLinkedList_DeleteAt(t *testing.T) {
err error
}{
{description: "delete item with negative position",
original: newList(),
original: NewLinkedList[int](),
modified: nil,
pos: -1,
err: ErrPositionNegative},
{description: "delete item in empty list",
original: newList(),
original: NewLinkedList[int](),
modified: nil,
pos: 0,
err: ErrEmptyList},
{description: "delete item in position not found",
original: newList(1, 2, 3),
modified: newList(),
original: NewLinkedList(1, 2, 3),
modified: NewLinkedList[int](),
pos: 5,
err: ErrNodeNotFound},
{description: "delete item in first position",
original: newList(1, 2, 3),
modified: newList(2, 3),
original: NewLinkedList(1, 2, 3),
modified: NewLinkedList(2, 3),
pos: 0,
err: nil},
{description: "delete item in middle position",
original: newList(1, 2, 3),
modified: newList(1, 3),
original: NewLinkedList(1, 2, 3),
modified: NewLinkedList(1, 3),
pos: 1,
err: nil},
{description: "delete item in last position",
original: newList(1, 2, 3),
modified: newList(1, 2),
original: NewLinkedList(1, 2, 3),
modified: NewLinkedList(1, 2),
pos: 2,
err: nil},
}
@@ -253,14 +253,6 @@ func TestLinkedList_DeleteAt(t *testing.T) {
}
}
func newList(items ...int) *LinkedList[int] {
lst := &LinkedList[int]{}
for _, item := range items {
lst.PushBack(item)
}
return lst
}
func compareLists(lst1, lst2 *LinkedList[int]) bool {
for it := lst1.Iterator(); it.HasNext(); {
i, item1 := it.NextWithIndex()

View File

@@ -1,6 +1,9 @@
package collection
import "fmt"
import (
"fmt"
"strings"
)
var (
// ErrEmptyStack is error when you have an empty stack structure
@@ -12,6 +15,15 @@ type Stack[E any] struct {
items []E
}
// NewStack is a constructor function for stack
func NewStack[E any](items ...E) *Stack[E] {
stack := &Stack[E]{}
for _, item := range items {
stack.Push(item)
}
return stack
}
// Size returns the number of items in the stack.
func (s *Stack[E]) Size() int {
return len(s.items)
@@ -47,3 +59,20 @@ func (s *Stack[E]) Push(item E) error {
s.items = append(s.items, item)
return nil
}
func (s *Stack[E]) String() string {
var sb strings.Builder
sb.WriteString("[")
for i := 0; i < s.Size(); i++ {
var str string
item := s.items[i]
if i >= s.Size()-1 {
str = fmt.Sprintf("%v", item)
} else {
str = fmt.Sprintf("%v, ", item)
}
sb.WriteString(str)
}
sb.WriteString("]")
return sb.String()
}

View File

@@ -1,9 +1,7 @@
package collection_test
package collection
import (
"testing"
"github.com/asd/pkg/collection"
)
type pair struct {
@@ -13,22 +11,22 @@ type pair struct {
var staticTests = []struct {
description string
input *collection.Stack[int]
input *Stack[int]
empty bool
size int
top pair
}{
{"empty stack", newStack([]int{}), true, 0, pair{0, collection.ErrEmptyStack}},
{"stack with items", newStack([]int{1, 2, 3}), false, 3, pair{3, nil}},
{"empty stack", NewStack[int](), true, 0, pair{0, ErrEmptyStack}},
{"stack with items", NewStack(1, 2, 3), false, 3, pair{3, nil}},
}
var popTests = []struct {
description string
input *collection.Stack[int]
input *Stack[int]
item pair
}{
{"empty stack pop item", newStack([]int{}), pair{0, collection.ErrEmptyStack}},
{"stack with items pop item", newStack([]int{1, 2, 3}), pair{3, nil}},
{"empty stack pop item", NewStack[int](), pair{0, ErrEmptyStack}},
{"stack with items pop item", NewStack(1, 2, 3), pair{3, nil}},
}
var pushTests = []struct {
@@ -79,7 +77,7 @@ func TestPush(t *testing.T) {
for i, tt := range pushTests {
t.Logf("Test %v: %s\n", i, tt.description)
stack := &collection.Stack[int]{}
stack := NewStack[int]()
for _, item := range tt.items {
stack.Push(item)
}
@@ -89,11 +87,3 @@ func TestPush(t *testing.T) {
}
}
}
func newStack(slice []int) *collection.Stack[int] {
stack := &collection.Stack[int]{}
for _, x := range slice {
stack.Push(x)
}
return stack
}