generic queue
This commit is contained in:
parent
6fe973096e
commit
cd3878d698
3 changed files with 19 additions and 24 deletions
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
2
go.mod
|
@ -1,3 +1,3 @@
|
||||||
module github.com/fotonmoton/algorithms
|
module github.com/fotonmoton/algorithms
|
||||||
|
|
||||||
go 1.16
|
go 1.18
|
||||||
|
|
Loading…
Reference in a new issue