From ade567a62050259d6964fe3b665645b4a598a691 Mon Sep 17 00:00:00 2001 From: dudaodong Date: Thu, 10 Feb 2022 17:30:37 +0800 Subject: [PATCH] feat: add ArrayQueue data structure --- datastructure/arrayqueue.go | 92 ++++++++++++++++++++++++++++++++ datastructure/arrayqueue_test.go | 90 +++++++++++++++++++++++++++++++ 2 files changed, 182 insertions(+) create mode 100644 datastructure/arrayqueue.go create mode 100644 datastructure/arrayqueue_test.go diff --git a/datastructure/arrayqueue.go b/datastructure/arrayqueue.go new file mode 100644 index 0000000..77d0f19 --- /dev/null +++ b/datastructure/arrayqueue.go @@ -0,0 +1,92 @@ +package datastructure + +import ( + "errors" + "fmt" + "reflect" +) + +// ArrayQueue implements queue with slice +type ArrayQueue[T any] struct { + data []T + length int +} + +// NewArrayQueue return a empty ArrayQueue pointer +func NewArrayQueue[T any](values ...T) *ArrayQueue[T] { + data := make([]T, len(values)) + for i, v := range values { + data[i] = v + } + return &ArrayQueue[T]{data: data, length: len(values)} +} + +// Data return queue data +func (q *ArrayQueue[T]) Data() []T { + return q.data +} + +// Size return length of queue data +func (q *ArrayQueue[T]) Size() int { + return q.length +} + +// IsEmpty checks if queue is empty or not +func (q *ArrayQueue[T]) IsEmpty() bool { + return q.length == 0 +} + +// Front return front value of queue +func (q *ArrayQueue[T]) Front() T { + return q.data[0] +} + +// Back return back value of queue +func (q *ArrayQueue[T]) Back() T { + return q.data[q.length-1] +} + +// EnQueue put element into queue +func (q *ArrayQueue[T]) EnQueue(value T) { + q.data = append(q.data, value) + q.length++ +} + +// DeQueue get the head element of queue, if queue is empty, return nil and error +func (q *ArrayQueue[T]) DeQueue() (*T, error) { + if q.IsEmpty() { + return nil, errors.New("queue is empty") + } + + headItem := q.data[0] + q.data = q.data[1:] + q.length-- + + return &headItem, nil +} + +// Clear the queue data +func (q *ArrayQueue[T]) Clear() { + q.data = []T{} + q.length = 0 +} + +// Contain checks if the value is in queue or not +func (q *ArrayQueue[T]) Contain(value T) bool { + for _, v := range q.data { + if reflect.DeepEqual(v, value) { + return true + } + } + return false +} + +// Print queue data +func (q *ArrayQueue[T]) Print() { + info := "[" + for _, v := range q.data { + info += fmt.Sprintf("%+v, ", v) + } + info += "]" + fmt.Println(info) +} diff --git a/datastructure/arrayqueue_test.go b/datastructure/arrayqueue_test.go new file mode 100644 index 0000000..7b0e2f7 --- /dev/null +++ b/datastructure/arrayqueue_test.go @@ -0,0 +1,90 @@ +package datastructure + +import ( + "testing" + + "github.com/duke-git/lancet/internal" +) + +func TestArrayQueue_EnQueue(t *testing.T) { + assert := internal.NewAssert(t, "TestArrayQueue_EnQueue") + + queue := NewArrayQueue[int]() + queue.EnQueue(1) + queue.EnQueue(2) + queue.EnQueue(3) + + expected := []int{1, 2, 3} + data := queue.Data() + size := queue.Size() + + queue.Print() + + assert.Equal(expected, data) + assert.Equal(3, size) +} + +func TestArrayQueue_DeQueue(t *testing.T) { + assert := internal.NewAssert(t, "TestArrayQueue_DeQueue") + + queue := NewArrayQueue(1, 2, 3) + + val, err := queue.DeQueue() + if err != nil { + t.Fail() + } + + queue.Print() + assert.Equal(1, *val) + + assert.Equal([]int{2, 3}, queue.Data()) +} + +func TestArrayQueue_Front(t *testing.T) { + assert := internal.NewAssert(t, "TestArrayQueue_Front") + + queue := NewArrayQueue(1, 2, 3) + val := queue.Front() + + queue.Print() + + assert.Equal(1, val) + assert.Equal([]int{1, 2, 3}, queue.Data()) +} + +func TestArrayQueue_Back(t *testing.T) { + assert := internal.NewAssert(t, "TestArrayQueue_Back") + + queue := NewArrayQueue(1, 2, 3) + val := queue.Back() + + queue.Print() + + assert.Equal(3, val) + assert.Equal([]int{1, 2, 3}, queue.Data()) +} + +func TestArrayQueue_Contain(t *testing.T) { + assert := internal.NewAssert(t, "TestArrayQueue_Contain") + + queue := NewArrayQueue(1, 2, 3) + + assert.Equal(true, queue.Contain(1)) + assert.Equal(false, queue.Contain(4)) +} + +func TestArrayQueue_Clear(t *testing.T) { + assert := internal.NewAssert(t, "TestArrayQueue_Clear") + + queue := NewArrayQueue[int]() + assert.Equal(true, queue.IsEmpty()) + assert.Equal(0, queue.Size()) + + queue.EnQueue(1) + assert.Equal(false, queue.IsEmpty()) + assert.Equal(1, queue.Size()) + + queue.Clear() + assert.Equal(true, queue.IsEmpty()) + assert.Equal(0, queue.Size()) +}