generic queue

This commit is contained in:
Gregory 2021-12-15 23:35:58 +02:00
parent 6fe973096e
commit cd3878d698
3 changed files with 19 additions and 24 deletions

View file

@ -1,37 +1,32 @@
package queue package queue
// "Generic" item. type Queue[T any] interface {
// When type parameters will land this type became Enqueue(T)
// type Item[T any] T Dequeue() T
type Item interface{}
type Queue interface {
Enqueue(Item)
Dequeue() Item
Size() int Size() int
IsEmpty() bool IsEmpty() bool
} }
// We use linked list as internal data structure // We use linked list as internal data structure
// to get O(1) speed for push and pop opeartions // to get O(1) speed for push and pop opeartions
type node struct { type node[Item any] struct {
item Item item Item
next *node next *node[Item]
} }
type queue struct { type queue[OfType any] struct {
size int size int
head *node head *node[OfType]
tail *node tail *node[OfType]
} }
func NewQueue() Queue { func NewQueue[OfType any]() Queue[OfType] {
return &queue{} return &queue[OfType]{}
} }
func (q *queue) Enqueue(item Item) { func (q *queue[T]) Enqueue(item T) {
oldTail := q.tail oldTail := q.tail
q.tail = &node{item: item, next: nil} q.tail = &node[T]{item: item, next: nil}
if q.IsEmpty() { if q.IsEmpty() {
q.head = q.tail q.head = q.tail
} else { } else {
@ -40,7 +35,7 @@ func (q *queue) Enqueue(item Item) {
q.size++ q.size++
} }
func (q *queue) Dequeue() Item { func (q *queue[T]) Dequeue() T {
first := q.head first := q.head
q.head = q.head.next q.head = q.head.next
if q.IsEmpty() { if q.IsEmpty() {
@ -50,10 +45,10 @@ func (q *queue) Dequeue() Item {
return first.item return first.item
} }
func (q *queue) Size() int { func (q *queue[T]) Size() int {
return q.size return q.size
} }
func (q *queue) IsEmpty() bool { func (q *queue[T]) IsEmpty() bool {
return q.head == nil return q.head == nil
} }

View file

@ -6,13 +6,13 @@ import (
) )
func TestSimple(t *testing.T) { func TestSimple(t *testing.T) {
queue := NewQueue() queue := NewQueue[int]()
queue.Enqueue(10) queue.Enqueue(10)
queue.Enqueue(20) queue.Enqueue(20)
queue.Enqueue(30) queue.Enqueue(30)
first, second := queue.Dequeue().(int), queue.Dequeue().(int) first, second := queue.Dequeue(), queue.Dequeue()
if first != 10 && second != 20 { if first != 10 && second != 20 {
log.Fatal("wrong order") log.Fatal("wrong order")
@ -20,7 +20,7 @@ func TestSimple(t *testing.T) {
} }
func TestSize(t *testing.T) { func TestSize(t *testing.T) {
queue := NewQueue() queue := NewQueue[int]()
if queue.Size() != 0 { if queue.Size() != 0 {
log.Fatal("empty queue should have size 0") log.Fatal("empty queue should have size 0")

2
go.mod
View file

@ -1,3 +1,3 @@
module github.com/fotonmoton/algorithms module github.com/fotonmoton/algorithms
go 1.16 go 1.18