Merge pull request #148 from AryanAhadinia/issue_146

Add Queue
pull/202/head
Emir Pasic 2 years ago committed by GitHub
commit 77ed4cc146
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -18,6 +18,9 @@ Implementation of various data structures and algorithms in Go.
- [ArrayList](#arraylist)
- [SinglyLinkedList](#singlylinkedlist)
- [DoublyLinkedList](#doublylinkedlist)
- [Queues](#queues)
- [LinkedListQueue](#linkedlistqueue)
- [ArrayQueue](#arrayqueue)
- [Sets](#sets)
- [HashSet](#hashset)
- [TreeSet](#treeset)
@ -76,6 +79,9 @@ Containers are either ordered or unordered. All ordered containers provide [stat
| | [ArrayList](#arraylist) | yes | yes* | yes | index |
| | [SinglyLinkedList](#singlylinkedlist) | yes | yes | yes | index |
| | [DoublyLinkedList](#doublylinkedlist) | yes | yes* | yes | index |
| [Queues](#queues) |
| | [LinkedListQueues](#linkedlistqueues) | yes | yes | no | index |
| | [ArrayQueues](#arrayqueues) | yes | yes* | no | index |
| [Sets](#sets) |
| | [HashSet](#hashset) | no | no | no | index |
| | [TreeSet](#treeset) | yes | yes* | yes | index |
@ -416,6 +422,80 @@ func main() {
}
```
### Queues
A queue that represents a first-in-first-out (FIFO) data structure. The usual enqueue and dequeue operations are provided, as well as a method to peek at the first item in the queue.
Implements [Container](#containers) interface.
```go
type Queue interface {
Enqueue(value interface{})
Dequeue() (value interface{}, ok bool)
Peek() (value interface{}, ok bool)
containers.Container
// Empty() bool
// Size() int
// Clear()
// Values() []interface{}
}
```
#### LinkedListQueue
A [queue](#queues) based on a [linked list](#singlylinkedlist).
Implements [Queue](#queues), [IteratorWithIndex](#iteratorwithindex), [JSONSerializer](#jsonserializer) and [JSONDeserializer](#jsondeserializer) interfaces.
```go
package main
import ll1 "github.com/emirpasic/gods/stacks/linkedlistqueue"
func main() {
queue := llq.New() // empty
queue.Enqueue(1) // 1
queue.Enqueue(2) // 1, 2
queue.Values() // 1, 2
_, _ = queue.Peek() // 1, true
_, _ = queue.Dequeue() // 1, true
_, _ = queue.Dequeue() // 2, true
_, _ = queue.Dequeue() // nil, false
queue.Enqueue(1) // 1
queue.Clear() // empty
queue.Empty() // true
queue.Size() // 0
}
```
#### ArrayQueue
A [queue](#queues) based on a [array list](#arraylist).
Implements [Queue](#queues), [IteratorWithIndex](#iteratorwithindex), [JSONSerializer](#jsonserializer) and [JSONDeserializer](#jsondeserializer) interfaces.
```go
package main
import ll1 "github.com/emirpasic/gods/stacks/linkedlistqueue"
func main() {
queue := llq.New() // empty
queue.Enqueue(1) // 1
queue.Enqueue(2) // 1, 2
queue.Values() // 1, 2
_, _ = queue.Peek() // 1, true
_, _ = queue.Dequeue() // 1, true
_, _ = queue.Dequeue() // 2, true
_, _ = queue.Dequeue() // nil, false
queue.Enqueue(1) // 1
queue.Clear() // empty
queue.Empty() // true
queue.Size() // 0
}
```
### Maps
A Map is a data structure that maps keys to values. A map cannot contain duplicate keys and each key can map to at most one value.

@ -0,0 +1,87 @@
// Copyright (c) 2021, Aryan Ahadinia. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package arrayqueue implements a queue backed by a array-list.
//
// Structure is not thread safe.
//
// Reference: https://en.wikipedia.org/wiki/Queue_(abstract_data_type)
package arrayqueue
import (
"fmt"
"strings"
"github.com/emirpasic/gods/lists/arraylist"
"github.com/emirpasic/gods/queues"
)
func assertQueueImplementation() {
var _ queues.Queue = (*Queue)(nil)
}
// Queue holds elements in an array-list
type Queue struct {
list *arraylist.List
}
// New instantiates a new empty queue
func New() *Queue {
return &Queue{list: arraylist.New()}
}
// Enqueue adds a value to the end of the queue
func (queue *Queue) Enqueue(value interface{}) {
queue.list.Add(value)
}
// Dequeue removes first element of the queue and returns it, or nil if queue is empty.
// Second return parameter is true, unless the queue was empty and there was nothing to dequeue.
func (queue *Queue) Dequeue() (value interface{}, ok bool) {
value, ok = queue.list.Get(0)
queue.list.Remove(0)
return
}
// Peek returns first element of the queue without removing it, or nil if queue is empty.
// Second return parameter is true, unless the queue was empty and there was nothing to peek.
func (queue *Queue) Peek() (value interface{}, ok bool) {
return queue.list.Get(0)
}
// Empty returns true if queue does not contain any elements.
func (queue *Queue) Empty() bool {
return queue.list.Empty()
}
// Size returns number of elements within the queue.
func (queue *Queue) Size() int {
return queue.list.Size()
}
// Clear removes all elements from the queue.
func (queue *Queue) Clear() {
queue.list.Clear()
}
// Values returns all elements in the queue (FIFO order).
func (queue *Queue) Values() []interface{} {
return queue.list.Values()
}
// String returns a string representation of container
func (queue *Queue) String() string {
str := "ArrayQueue\n"
values := []string{}
for _, value := range queue.list.Values() {
values = append(values, fmt.Sprintf("%v", value))
}
str += strings.Join(values, ", ")
return str
}
// Check that the index is within bounds of the list
func (queue *Queue) withinRange(index int) bool {
return index >= 0 && index < queue.list.Size()
}

@ -0,0 +1,278 @@
// Copyright (c) 2021, Aryan Ahadinia. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package arrayqueue
import (
"fmt"
"testing"
)
func TestQueueEnqueue(t *testing.T) {
queue := New()
if actualValue := queue.Empty(); actualValue != true {
t.Errorf("Got %v expected %v", actualValue, true)
}
queue.Enqueue(1)
queue.Enqueue(2)
queue.Enqueue(3)
if actualValue := queue.Values(); actualValue[0].(int) != 1 || actualValue[1].(int) != 2 || actualValue[2].(int) != 3 {
t.Errorf("Got %v expected %v", actualValue, "[1,2,3]")
}
if actualValue := queue.Empty(); actualValue != false {
t.Errorf("Got %v expected %v", actualValue, false)
}
if actualValue := queue.Size(); actualValue != 3 {
t.Errorf("Got %v expected %v", actualValue, 3)
}
if actualValue, ok := queue.Peek(); actualValue != 1 || !ok {
t.Errorf("Got %v expected %v", actualValue, 1)
}
}
func TestQueuePeek(t *testing.T) {
queue := New()
if actualValue, ok := queue.Peek(); actualValue != nil || ok {
t.Errorf("Got %v expected %v", actualValue, nil)
}
queue.Enqueue(1)
queue.Enqueue(2)
queue.Enqueue(3)
if actualValue, ok := queue.Peek(); actualValue != 1 || !ok {
t.Errorf("Got %v expected %v", actualValue, 1)
}
}
func TestQueueDequeue(t *testing.T) {
queue := New()
queue.Enqueue(1)
queue.Enqueue(2)
queue.Enqueue(3)
queue.Dequeue()
if actualValue, ok := queue.Peek(); actualValue != 2 || !ok {
t.Errorf("Got %v expected %v", actualValue, 2)
}
if actualValue, ok := queue.Dequeue(); actualValue != 2 || !ok {
t.Errorf("Got %v expected %v", actualValue, 2)
}
if actualValue, ok := queue.Dequeue(); actualValue != 3 || !ok {
t.Errorf("Got %v expected %v", actualValue, 3)
}
if actualValue, ok := queue.Dequeue(); actualValue != nil || ok {
t.Errorf("Got %v expected %v", actualValue, nil)
}
if actualValue := queue.Empty(); actualValue != true {
t.Errorf("Got %v expected %v", actualValue, true)
}
if actualValue := queue.Values(); len(actualValue) != 0 {
t.Errorf("Got %v expected %v", actualValue, "[]")
}
}
func TestQueueIterator(t *testing.T) {
queue := New()
queue.Enqueue("a")
queue.Enqueue("b")
queue.Enqueue("c")
// Iterator
it := queue.Iterator()
count := 0
for it.Next() {
count++
index := it.Index()
value := it.Value()
switch index {
case 0:
if actualValue, expectedValue := value, "a"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
case 1:
if actualValue, expectedValue := value, "b"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
case 2:
if actualValue, expectedValue := value, "c"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
default:
t.Errorf("Too many")
}
if actualValue, expectedValue := index, count-1; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
}
if actualValue, expectedValue := count, 3; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
queue.Clear()
it = queue.Iterator()
for it.Next() {
t.Errorf("Shouldn't iterate on empty queue")
}
}
func TestQueueIteratorBegin(t *testing.T) {
queue := New()
it := queue.Iterator()
it.Begin()
queue.Enqueue("a")
queue.Enqueue("b")
queue.Enqueue("c")
for it.Next() {
}
it.Begin()
it.Next()
if index, value := it.Index(), it.Value(); index != 0 || value != "a" {
t.Errorf("Got %v,%v expected %v,%v", index, value, 0, "a")
}
}
func TestQueueIteratorFirst(t *testing.T) {
queue := New()
it := queue.Iterator()
if actualValue, expectedValue := it.First(), false; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
queue.Enqueue("a")
queue.Enqueue("b")
queue.Enqueue("c")
if actualValue, expectedValue := it.First(), true; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if index, value := it.Index(), it.Value(); index != 0 || value != "a" {
t.Errorf("Got %v,%v expected %v,%v", index, value, 0, "a")
}
}
func TestQueueSerialization(t *testing.T) {
queue := New()
queue.Enqueue("a")
queue.Enqueue("b")
queue.Enqueue("c")
var err error
assert := func() {
if actualValue, expectedValue := fmt.Sprintf("%s%s%s", queue.Values()...), "abc"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if actualValue, expectedValue := queue.Size(), 3; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if err != nil {
t.Errorf("Got error %v", err)
}
}
assert()
json, err := queue.ToJSON()
assert()
err = queue.FromJSON(json)
assert()
}
func benchmarkEnqueue(b *testing.B, queue *Queue, size int) {
for i := 0; i < b.N; i++ {
for n := 0; n < size; n++ {
queue.Enqueue(n)
}
}
}
func benchmarkDequeue(b *testing.B, queue *Queue, size int) {
for i := 0; i < b.N; i++ {
for n := 0; n < size; n++ {
queue.Dequeue()
}
}
}
func BenchmarkLinkedListQueueDequeue100(b *testing.B) {
b.StopTimer()
size := 100
queue := New()
for n := 0; n < size; n++ {
queue.Enqueue(n)
}
b.StartTimer()
benchmarkDequeue(b, queue, size)
}
func BenchmarkLinkedListQueueDequeue1000(b *testing.B) {
b.StopTimer()
size := 1000
queue := New()
for n := 0; n < size; n++ {
queue.Enqueue(n)
}
b.StartTimer()
benchmarkDequeue(b, queue, size)
}
func BenchmarkLinkedListQueueDequeue10000(b *testing.B) {
b.StopTimer()
size := 10000
queue := New()
for n := 0; n < size; n++ {
queue.Enqueue(n)
}
b.StartTimer()
benchmarkDequeue(b, queue, size)
}
func BenchmarkLinkedListQueueDequeue100000(b *testing.B) {
b.StopTimer()
size := 100000
queue := New()
for n := 0; n < size; n++ {
queue.Enqueue(n)
}
b.StartTimer()
benchmarkDequeue(b, queue, size)
}
func BenchmarkLinkedListQueueEnqueue100(b *testing.B) {
b.StopTimer()
size := 100
stack := New()
b.StartTimer()
benchmarkEnqueue(b, stack, size)
}
func BenchmarkLinkedListQueueEnqueue1000(b *testing.B) {
b.StopTimer()
size := 1000
queue := New()
for n := 0; n < size; n++ {
queue.Enqueue(n)
}
b.StartTimer()
benchmarkEnqueue(b, queue, size)
}
func BenchmarkLinkedListQueueEnqueue10000(b *testing.B) {
b.StopTimer()
size := 10000
queue := New()
for n := 0; n < size; n++ {
queue.Enqueue(n)
}
b.StartTimer()
benchmarkEnqueue(b, queue, size)
}
func BenchmarkLinkedListQueueEnqueue100000(b *testing.B) {
b.StopTimer()
size := 100000
queue := New()
for n := 0; n < size; n++ {
queue.Enqueue(n)
}
b.StartTimer()
benchmarkEnqueue(b, queue, size)
}

@ -0,0 +1,84 @@
// Copyright (c) 2021, Aryan Ahadinia. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package arrayqueue
import "github.com/emirpasic/gods/containers"
func assertIteratorImplementation() {
var _ containers.ReverseIteratorWithIndex = (*Iterator)(nil)
}
// Iterator returns a stateful iterator whose values can be fetched by an index.
type Iterator struct {
queue *Queue
index int
}
// Iterator returns a stateful iterator whose values can be fetched by an index.
func (queue *Queue) Iterator() Iterator {
return Iterator{queue: queue, index: -1}
}
// Next moves the iterator to the next element and returns true if there was a next element in the container.
// If Next() returns true, then next element's index and value can be retrieved by Index() and Value().
// If Next() was called for the first time, then it will point the iterator to the first element if it exists.
// Modifies the state of the iterator.
func (iterator *Iterator) Next() bool {
if iterator.index < iterator.queue.Size() {
iterator.index++
}
return iterator.queue.withinRange(iterator.index)
}
// Prev moves the iterator to the previous element and returns true if there was a previous element in the container.
// If Prev() returns true, then previous element's index and value can be retrieved by Index() and Value().
// Modifies the state of the iterator.
func (iterator *Iterator) Prev() bool {
if iterator.index >= 0 {
iterator.index--
}
return iterator.queue.withinRange(iterator.index)
}
// Value returns the current element's value.
// Does not modify the state of the iterator.
func (iterator *Iterator) Value() interface{} {
value, _ := iterator.queue.list.Get(iterator.index) // in order (FIFO)
return value
}
// Index returns the current element's index.
// Does not modify the state of the iterator.
func (iterator *Iterator) Index() int {
return iterator.index
}
// Begin resets the iterator to its initial state (one-before-first)
// Call Next() to fetch the first element if any.
func (iterator *Iterator) Begin() {
iterator.index = -1
}
// End moves the iterator past the last element (one-past-the-end).
// Call Prev() to fetch the last element if any.
func (iterator *Iterator) End() {
iterator.index = iterator.queue.Size()
}
// First moves the iterator to the first element and returns true if there was a first element in the container.
// If First() returns true, then first element's index and value can be retrieved by Index() and Value().
// Modifies the state of the iterator.
func (iterator *Iterator) First() bool {
iterator.Begin()
return iterator.Next()
}
// Last moves the iterator to the last element and returns true if there was a last element in the container.
// If Last() returns true, then last element's index and value can be retrieved by Index() and Value().
// Modifies the state of the iterator.
func (iterator *Iterator) Last() bool {
iterator.End()
return iterator.Prev()
}

@ -0,0 +1,22 @@
// Copyright (c) 2021, Aryan Ahadinia. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package arrayqueue
import "github.com/emirpasic/gods/containers"
func assertSerializationImplementation() {
var _ containers.JSONSerializer = (*Queue)(nil)
var _ containers.JSONDeserializer = (*Queue)(nil)
}
// ToJSON outputs the JSON representation of the queue.
func (queue *Queue) ToJSON() ([]byte, error) {
return queue.list.ToJSON()
}
// FromJSON populates the queue from the input JSON representation.
func (queue *Queue) FromJSON(data []byte) error {
return queue.list.FromJSON(data)
}

@ -0,0 +1,60 @@
// Copyright (c) 2021, Aryan Ahadinia. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package linkedlistqueue
import "github.com/emirpasic/gods/containers"
func assertIteratorImplementation() {
var _ containers.IteratorWithIndex = (*Iterator)(nil)
}
// Iterator returns a stateful iterator whose values can be fetched by an index.
type Iterator struct {
queue *Queue
index int
}
// Iterator returns a stateful iterator whose values can be fetched by an index.
func (queue *Queue) Iterator() Iterator {
return Iterator{queue: queue, index: -1}
}
// Next moves the iterator to the next element and returns true if there was a next element in the container.
// If Next() returns true, then next element's index and value can be retrieved by Index() and Value().
// If Next() was called for the first time, then it will point the iterator to the first element if it exists.
// Modifies the state of the iterator.
func (iterator *Iterator) Next() bool {
if iterator.index < iterator.queue.Size() {
iterator.index++
}
return iterator.queue.withinRange(iterator.index)
}
// Value returns the current element's value.
// Does not modify the state of the iterator.
func (iterator *Iterator) Value() interface{} {
value, _ := iterator.queue.list.Get(iterator.index) // in order (FIFO)
return value
}
// Index returns the current element's index.
// Does not modify the state of the iterator.
func (iterator *Iterator) Index() int {
return iterator.index
}
// Begin resets the iterator to its initial state (one-before-first)
// Call Next() to fetch the first element if any.
func (iterator *Iterator) Begin() {
iterator.index = -1
}
// First moves the iterator to the first element and returns true if there was a first element in the container.
// If First() returns true, then first element's index and value can be retrieved by Index() and Value().
// Modifies the state of the iterator.
func (iterator *Iterator) First() bool {
iterator.Begin()
return iterator.Next()
}

@ -0,0 +1,87 @@
// Copyright (c) 2021, Aryan Ahadinia. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package linkedlistqueue implements a queue backed by a singly-linked list.
//
// Structure is not thread safe.
//
// Reference: https://en.wikipedia.org/wiki/Queue_(abstract_data_type)
package linkedlistqueue
import (
"fmt"
"strings"
"github.com/emirpasic/gods/lists/singlylinkedlist"
"github.com/emirpasic/gods/queues"
)
func assertQueueImplementation() {
var _ queues.Queue = (*Queue)(nil)
}
// Queue holds elements in a singly-linked-list
type Queue struct {
list *singlylinkedlist.List
}
// New instantiates a new empty queue
func New() *Queue {
return &Queue{list: &singlylinkedlist.List{}}
}
// Enqueue adds a value to the end of the queue
func (queue *Queue) Enqueue(value interface{}) {
queue.list.Add(value)
}
// Dequeue removes first element of the queue and returns it, or nil if queue is empty.
// Second return parameter is true, unless the queue was empty and there was nothing to dequeue.
func (queue *Queue) Dequeue() (value interface{}, ok bool) {
value, ok = queue.list.Get(0)
queue.list.Remove(0)
return
}
// Peek returns first element of the queue without removing it, or nil if queue is empty.
// Second return parameter is true, unless the queue was empty and there was nothing to peek.
func (queue *Queue) Peek() (value interface{}, ok bool) {
return queue.list.Get(0)
}
// Empty returns true if queue does not contain any elements.
func (queue *Queue) Empty() bool {
return queue.list.Empty()
}
// Size returns number of elements within the queue.
func (queue *Queue) Size() int {
return queue.list.Size()
}
// Clear removes all elements from the queue.
func (queue *Queue) Clear() {
queue.list.Clear()
}
// Values returns all elements in the queue (FIFO order).
func (queue *Queue) Values() []interface{} {
return queue.list.Values()
}
// String returns a string representation of container
func (queue *Queue) String() string {
str := "LinkedListQueue\n"
values := []string{}
for _, value := range queue.list.Values() {
values = append(values, fmt.Sprintf("%v", value))
}
str += strings.Join(values, ", ")
return str
}
// Check that the index is within bounds of the list
func (queue *Queue) withinRange(index int) bool {
return index >= 0 && index < queue.list.Size()
}

@ -0,0 +1,278 @@
// Copyright (c) 2021, Aryan Ahadinia. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package linkedlistqueue
import (
"fmt"
"testing"
)
func TestQueueEnqueue(t *testing.T) {
queue := New()
if actualValue := queue.Empty(); actualValue != true {
t.Errorf("Got %v expected %v", actualValue, true)
}
queue.Enqueue(1)
queue.Enqueue(2)
queue.Enqueue(3)
if actualValue := queue.Values(); actualValue[0].(int) != 1 || actualValue[1].(int) != 2 || actualValue[2].(int) != 3 {
t.Errorf("Got %v expected %v", actualValue, "[1,2,3]")
}
if actualValue := queue.Empty(); actualValue != false {
t.Errorf("Got %v expected %v", actualValue, false)
}
if actualValue := queue.Size(); actualValue != 3 {
t.Errorf("Got %v expected %v", actualValue, 3)
}
if actualValue, ok := queue.Peek(); actualValue != 1 || !ok {
t.Errorf("Got %v expected %v", actualValue, 1)
}
}
func TestQueuePeek(t *testing.T) {
queue := New()
if actualValue, ok := queue.Peek(); actualValue != nil || ok {
t.Errorf("Got %v expected %v", actualValue, nil)
}
queue.Enqueue(1)
queue.Enqueue(2)
queue.Enqueue(3)
if actualValue, ok := queue.Peek(); actualValue != 1 || !ok {
t.Errorf("Got %v expected %v", actualValue, 1)
}
}
func TestQueueDequeue(t *testing.T) {
queue := New()
queue.Enqueue(1)
queue.Enqueue(2)
queue.Enqueue(3)
queue.Dequeue()
if actualValue, ok := queue.Peek(); actualValue != 2 || !ok {
t.Errorf("Got %v expected %v", actualValue, 2)
}
if actualValue, ok := queue.Dequeue(); actualValue != 2 || !ok {
t.Errorf("Got %v expected %v", actualValue, 2)
}
if actualValue, ok := queue.Dequeue(); actualValue != 3 || !ok {
t.Errorf("Got %v expected %v", actualValue, 3)
}
if actualValue, ok := queue.Dequeue(); actualValue != nil || ok {
t.Errorf("Got %v expected %v", actualValue, nil)
}
if actualValue := queue.Empty(); actualValue != true {
t.Errorf("Got %v expected %v", actualValue, true)
}
if actualValue := queue.Values(); len(actualValue) != 0 {
t.Errorf("Got %v expected %v", actualValue, "[]")
}
}
func TestQueueIterator(t *testing.T) {
queue := New()
queue.Enqueue("a")
queue.Enqueue("b")
queue.Enqueue("c")
// Iterator
it := queue.Iterator()
count := 0
for it.Next() {
count++
index := it.Index()
value := it.Value()
switch index {
case 0:
if actualValue, expectedValue := value, "a"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
case 1:
if actualValue, expectedValue := value, "b"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
case 2:
if actualValue, expectedValue := value, "c"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
default:
t.Errorf("Too many")
}
if actualValue, expectedValue := index, count-1; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
}
if actualValue, expectedValue := count, 3; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
queue.Clear()
it = queue.Iterator()
for it.Next() {
t.Errorf("Shouldn't iterate on empty queue")
}
}
func TestQueueIteratorBegin(t *testing.T) {
queue := New()
it := queue.Iterator()
it.Begin()
queue.Enqueue("a")
queue.Enqueue("b")
queue.Enqueue("c")
for it.Next() {
}
it.Begin()
it.Next()
if index, value := it.Index(), it.Value(); index != 0 || value != "a" {
t.Errorf("Got %v,%v expected %v,%v", index, value, 0, "a")
}
}
func TestQueueIteratorFirst(t *testing.T) {
queue := New()
it := queue.Iterator()
if actualValue, expectedValue := it.First(), false; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
queue.Enqueue("a")
queue.Enqueue("b")
queue.Enqueue("c")
if actualValue, expectedValue := it.First(), true; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if index, value := it.Index(), it.Value(); index != 0 || value != "a" {
t.Errorf("Got %v,%v expected %v,%v", index, value, 0, "a")
}
}
func TestQueueSerialization(t *testing.T) {
queue := New()
queue.Enqueue("a")
queue.Enqueue("b")
queue.Enqueue("c")
var err error
assert := func() {
if actualValue, expectedValue := fmt.Sprintf("%s%s%s", queue.Values()...), "abc"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if actualValue, expectedValue := queue.Size(), 3; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if err != nil {
t.Errorf("Got error %v", err)
}
}
assert()
json, err := queue.ToJSON()
assert()
err = queue.FromJSON(json)
assert()
}
func benchmarkEnqueue(b *testing.B, queue *Queue, size int) {
for i := 0; i < b.N; i++ {
for n := 0; n < size; n++ {
queue.Enqueue(n)
}
}
}
func benchmarkDequeue(b *testing.B, queue *Queue, size int) {
for i := 0; i < b.N; i++ {
for n := 0; n < size; n++ {
queue.Dequeue()
}
}
}
func BenchmarkLinkedListQueueDequeue100(b *testing.B) {
b.StopTimer()
size := 100
queue := New()
for n := 0; n < size; n++ {
queue.Enqueue(n)
}
b.StartTimer()
benchmarkDequeue(b, queue, size)
}
func BenchmarkLinkedListQueueDequeue1000(b *testing.B) {
b.StopTimer()
size := 1000
queue := New()
for n := 0; n < size; n++ {
queue.Enqueue(n)
}
b.StartTimer()
benchmarkDequeue(b, queue, size)
}
func BenchmarkLinkedListQueueDequeue10000(b *testing.B) {
b.StopTimer()
size := 10000
queue := New()
for n := 0; n < size; n++ {
queue.Enqueue(n)
}
b.StartTimer()
benchmarkDequeue(b, queue, size)
}
func BenchmarkLinkedListQueueDequeue100000(b *testing.B) {
b.StopTimer()
size := 100000
queue := New()
for n := 0; n < size; n++ {
queue.Enqueue(n)
}
b.StartTimer()
benchmarkDequeue(b, queue, size)
}
func BenchmarkLinkedListQueueEnqueue100(b *testing.B) {
b.StopTimer()
size := 100
stack := New()
b.StartTimer()
benchmarkEnqueue(b, stack, size)
}
func BenchmarkLinkedListQueueEnqueue1000(b *testing.B) {
b.StopTimer()
size := 1000
queue := New()
for n := 0; n < size; n++ {
queue.Enqueue(n)
}
b.StartTimer()
benchmarkEnqueue(b, queue, size)
}
func BenchmarkLinkedListQueueEnqueue10000(b *testing.B) {
b.StopTimer()
size := 10000
queue := New()
for n := 0; n < size; n++ {
queue.Enqueue(n)
}
b.StartTimer()
benchmarkEnqueue(b, queue, size)
}
func BenchmarkLinkedListQueueEnqueue100000(b *testing.B) {
b.StopTimer()
size := 100000
queue := New()
for n := 0; n < size; n++ {
queue.Enqueue(n)
}
b.StartTimer()
benchmarkEnqueue(b, queue, size)
}

@ -0,0 +1,22 @@
// Copyright (c) 2021, Aryan Ahadinia. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package linkedlistqueue
import "github.com/emirpasic/gods/containers"
func assertSerializationImplementation() {
var _ containers.JSONSerializer = (*Queue)(nil)
var _ containers.JSONDeserializer = (*Queue)(nil)
}
// ToJSON outputs the JSON representation of the queue.
func (queue *Queue) ToJSON() ([]byte, error) {
return queue.list.ToJSON()
}
// FromJSON populates the queue from the input JSON representation.
func (queue *Queue) FromJSON(data []byte) error {
return queue.list.FromJSON(data)
}

@ -0,0 +1,26 @@
// Copyright (c) 2021, Aryan Ahadinia. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package queues provides an abstract Queue interface.
//
// In computer science, a queue is a collection of entities that are maintained in a sequence and can be modified by the addition of entities at one end of the sequence and the removal of entities from the other end of the sequence. By convention, the end of the sequence at which elements are added is called the back, tail, or rear of the queue, and the end at which elements are removed is called the head or front of the queue, analogously to the words used when people line up to wait for goods or services.
// The operation of adding an element to the rear of the queue is known as enqueue, and the operation of removing an element from the front is known as dequeue. Other operations may also be allowed, often including a peek or front operation that returns the value of the next element to be dequeued without remove it.
//
// Reference: https://en.wikipedia.org/wiki/Queue_(abstract_data_type)
package queues
import "github.com/emirpasic/gods/containers"
// Queue interface that all queues implement
type Queue interface {
Enqueue(value interface{})
Dequeue() (value interface{}, ok bool)
Peek() (value interface{}, ok bool)
containers.Container
// Empty() bool
// Size() int
// Clear()
// Values() []interface{}
}
Loading…
Cancel
Save