Skip to content

Commit

Permalink
Merge pull request #3 from modern-dev/queue
Browse files Browse the repository at this point in the history
feat: queue implementation, extend deque API. #patch
  • Loading branch information
virtyaluk authored Nov 26, 2020
2 parents 464d3bb + 942a7db commit bfa621c
Show file tree
Hide file tree
Showing 4 changed files with 215 additions and 6 deletions.
32 changes: 30 additions & 2 deletions deque.go2
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,9 @@ func (d *Deque[T]) NotEmpty() bool {
return !d.IsEmpty()
}

// Size returns the number of elements in Deque
// Len returns the number of elements in Deque
// Complexity - O(1).
func (d *Deque[T]) Size() int {
func (d *Deque[T]) Len() int {
return d.length
}

Expand Down Expand Up @@ -112,6 +112,34 @@ func (d *Deque[T]) DequeueFront() T {
return value
}

// Front returns values of the first element in Deque
// Complexity - O(1).
func (d *Deque[T]) Front() T {
if d.IsEmpty() {
panic(OutOfRangeError)
}

if d.head == nil {
return d.tail.Value
}

return d.head.Value
}

// Back returns values of the last element in Deque
// Complexity - O(1).
func (d *Deque[T]) Back() T {
if d.IsEmpty() {
panic(OutOfRangeError)
}

if d.tail == nil {
return d.head.Value
}

return d.tail.Value
}

func (d *Deque[T]) insertIntoEmpty(node *dequeNode[T]) {
d.tail = node
d.head = node
Expand Down
60 changes: 56 additions & 4 deletions deque_test.go2
Original file line number Diff line number Diff line change
Expand Up @@ -63,20 +63,72 @@ func TestDequeueBack(t *testing.T) {
}
}

func TestDequeueFrontPanicOnEmpty(t *testing.T) {
func TestDequeueFrontDequeuePanicOnEmpty(t *testing.T) {
assertPanic(func() {
d := NewDeque[int]()
d.DequeueFront()
}, OutOfRangeError, t)
}

func TestDequeueBackPanicOnEmpty(t *testing.T) {
func TestDequeueDequeueBackPanicOnEmpty(t *testing.T) {
assertPanic(func() {
d := NewDeque[int]()
d.DequeueBack()
}, OutOfRangeError, t)
}

func TestDequeFront(t *testing.T) {
d := NewDeque[string]()

d.EnqueueBack("string")

value := d.Front()
if value != "string" {
t.Errorf("Expected to get %s, got %s", "string", value)
}

d.EnqueueBack("value")
d.EnqueueFront("front")

value = d.Front()
if value != "front" {
t.Errorf("Expected to get %s, got %s", "front", value)
}
}

func TestDequeBack(t *testing.T) {
d := NewDeque[string]()

d.EnqueueBack("string")

value := d.Back()
if value != "string" {
t.Errorf("Expected to get %s, got %s", "string", value)
}

d.EnqueueBack("value")
d.EnqueueFront("front")

value = d.Back()
if value != "value" {
t.Errorf("Expected to get %s, got %s", "value", value)
}
}

func TestDequeueBackPanicOnEmpty(t *testing.T) {
assertPanic(func() {
d := NewDeque[int]()
d.Back()
}, OutOfRangeError, t)
}

func TestDequeueFrontPanicOnEmpty(t *testing.T) {
assertPanic(func() {
d := NewDeque[int]()
d.Front()
}, OutOfRangeError, t)
}

func TestDeque(t *testing.T) {
d := NewDeque[int]()

Expand Down Expand Up @@ -116,7 +168,7 @@ func assertPanic(blockFn func(), err error, t *testing.T) {
}

func checkDequeSize[P any](deque *Deque[P], expected int, t *testing.T) {
if deque.Size() != expected {
t.Errorf("Deque should have size %d but got %d", expected, deque.Size())
if deque.Len() != expected {
t.Errorf("Deque should have size %d but got %d", expected, deque.Len())
}
}
53 changes: 53 additions & 0 deletions queue.go2
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// Copyright 2020. The GTL Authors. All rights reserved.
// https://github.com/modern-dev/gtl
// Use of this source code is governed by the MIT
// license that can be found in the LICENSE file.

package gtl

// Queue is a container adapter that gives the programmer the functionality of a queue
// - specifically, a FIFO (first-in, first-out) data structure.
type Queue[T any] struct {
deque *Deque[T]
}

// NewQueue creates new empty Queue of given type
func NewQueue[T any]() *Queue[T] {
return &Queue[T]{deque: NewDeque[T]()}
}

// Len returns number of elements in queue
// Complexity O(1)
func (q *Queue[T]) Len() int {
return q.deque.Len()
}

// IsEmpty checks if Queue has no element
// Complexity O(1)
func (q *Queue[T]) IsEmpty() bool {
return q.deque.IsEmpty()
}

// NotEmpty checks if Queue has elements
// Complexity O(1)
func (q *Queue[T]) NotEmpty() bool {
return q.deque.NotEmpty()
}

// Peek returns value of the first element in Queue
// Complexity O(1)
func (q *Queue[T]) Peek() T {
return q.deque.Front()
}

// Enqueue add element in front of queue
// Complexity O(1)
func (q *Queue[T]) Enqueue(element T) {
q.deque.EnqueueFront(element)
}

// Enqueue removes and returns first element of queue
// Complexity O(1)
func (q *Queue[T]) Dequeue() T {
return q.deque.DequeueFront()
}
76 changes: 76 additions & 0 deletions queue_test.go2
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package gtl

import "testing"

const queueEnqueuesCount = 300

func TestNewQueue(t *testing.T) {
structQueue := NewQueue[struct{}]()
intQueue := NewQueue[int]()
sliceQueue := NewQueue[[]float64]()

checkQueueSize(structQueue, 0, t)
checkQueueSize(intQueue, 0, t)
checkQueueSize(sliceQueue, 0, t)
}

func TestEnqueue(t *testing.T) {
queue := NewQueue[int]()

for i := 0; i < queueEnqueuesCount; i++ {
queue.Enqueue(i)
checkQueueSize(queue, i+1, t)
}
}

func TestDequeue(t *testing.T) {
queue := NewQueue[int]()

queue.Enqueue(1)
el := queue.Dequeue()

checkQueueSize(queue, 0, t)
if el != 1 {
t.Errorf("Expected to get %d, got %d", 1, el)
}
}

func TestPeek(t *testing.T) {
queue := NewQueue[int]()

queue.Enqueue(1)
el := queue.Peek()

checkQueueSize(queue, 1, t)
if el != 1 {
t.Errorf("Expected to get %d, got %d", 1, el)
}
}

func TestQueue(t *testing.T) {
queue := NewQueue[float64]()

for i := 0; i < queueEnqueuesCount; i++ {
queue.Enqueue(float64(i))
}

checkQueueSize(queue, queueEnqueuesCount, t)

if queue.NotEmpty() != true {
t.Errorf("Queue should not be empty")
}

for i := queueEnqueuesCount; i > 0; i-- {
queue.Dequeue()
}

if queue.IsEmpty() != true {
t.Errorf("Deque should be empty")
}
}

func checkQueueSize[T any](queue *Queue[T], expected int, t *testing.T) {
if queue.Len() != expected {
t.Errorf("Queue should have size %d but got %d", expected, queue.Len())
}
}

0 comments on commit bfa621c

Please sign in to comment.