Implemented Queue data structure
This commit is contained in:
59
pkg/collection/queue.go
Normal file
59
pkg/collection/queue.go
Normal 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()
|
||||
}
|
||||
94
pkg/collection/queue_test.go
Normal file
94
pkg/collection/queue_test.go
Normal 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)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user