Implemented Queue data structure

This commit is contained in:
Fabio Scotto di Santolo
2023-01-06 11:42:00 +01:00
parent ac20be21e4
commit 50f4b83504
2 changed files with 153 additions and 0 deletions

59
pkg/collection/queue.go Normal file
View File

@@ -0,0 +1,59 @@
package collection
import (
"fmt"
"strings"
)
var (
ErrEmptyQueue = fmt.Errorf("empty queue")
)
type Queue[E any] struct {
items []E
}
func NewQueue[E any](items ...E) *Queue[E] {
if items == nil {
items = make([]E, 0)
}
return &Queue[E]{items}
}
func (q *Queue[E]) Empty() bool {
return q.Size() == 0
}
func (q *Queue[E]) Size() int {
return len(q.items)
}
func (q *Queue[E]) Enqueue(item E) {
q.items = append(q.items, item)
}
func (q *Queue[E]) Dequeue() (E, error) {
if q.Empty() {
return *new(E), ErrEmptyQueue
}
item := q.items[0]
q.items = q.items[1:]
return item, nil
}
func (q *Queue[E]) String() string {
var sb strings.Builder
sb.WriteString("[")
for i := 0; i < q.Size(); i++ {
var s string
item := q.items[i]
if i >= q.Size()-1 {
s = fmt.Sprintf("%v", item)
} else {
s = fmt.Sprintf("%v, ", item)
}
sb.WriteString(s)
}
sb.WriteString("]")
return sb.String()
}

View File

@@ -0,0 +1,94 @@
package collection
import (
"reflect"
"testing"
)
func TestQueue_Empty(t *testing.T) {
useCases := []struct {
description string
queue *Queue[int]
want bool
}{
{description: "empty queue", queue: NewQueue[int](), want: true},
{description: "non empty queue", queue: NewQueue(1), want: false},
}
for _, tt := range useCases {
result := tt.queue.Empty()
if result != tt.want {
t.Errorf("test: %s, want %v got %v", tt.description, tt.want, result)
}
}
}
func TestQueue_Size(t *testing.T) {
useCases := []struct {
description string
queue *Queue[int]
want int
}{
{description: "empty queue", queue: NewQueue[int](), want: 0},
{description: "non empty queue", queue: NewQueue(1), want: 1},
}
for _, tt := range useCases {
result := tt.queue.Size()
if result != tt.want {
t.Errorf("test: %s, want %v got %v", tt.description, tt.want, result)
}
}
}
func TestQueue_Enqueue(t *testing.T) {
useCases := []struct {
description string
original *Queue[int]
modified *Queue[int]
item int
}{
{description: "enqueue one item in empty queue", original: NewQueue[int](), modified: NewQueue(1), item: 1},
{description: "enqueue one item in full queue", original: NewQueue(1, 2, 3), modified: NewQueue(1, 2, 3, 4), item: 4},
}
for _, tt := range useCases {
tt.original.Enqueue(tt.item)
if !reflect.DeepEqual(tt.original.items, tt.modified.items) {
t.Errorf("test: %s, want %v got %v", tt.description, tt.modified, tt.original)
}
}
}
func TestQueue_Dequeue(t *testing.T) {
useCases := []struct {
description string
original *Queue[int]
modified *Queue[int]
item int
err error
}{
{description: "dequeue one item in empty queue",
original: NewQueue[int](),
modified: NewQueue[int](),
item: 0,
err: ErrEmptyQueue},
{description: "dequeue one item in single item queue",
original: NewQueue(1),
modified: NewQueue[int](),
item: 1,
err: nil},
{description: "dequeue one item in full queue",
original: NewQueue(1, 2, 3),
modified: NewQueue(2, 3),
item: 1,
err: nil},
}
for _, tt := range useCases {
_, err := tt.original.Dequeue()
if !reflect.DeepEqual(tt.original.items, tt.modified.items) || err != tt.err {
t.Errorf("test: %s, want %v got %v", tt.description, tt.modified, tt.original)
}
}
}