Skip to content

Commit

Permalink
Merge pull request #9 from 246859/feat-linked-queue
Browse files Browse the repository at this point in the history
Feat linked queue
  • Loading branch information
246859 authored Dec 27, 2023
2 parents f755ac8 + 55a2671 commit 2025af6
Show file tree
Hide file tree
Showing 3 changed files with 173 additions and 2 deletions.
3 changes: 1 addition & 2 deletions TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,8 @@

- queue
- ArrayQueue ✔️
- LinkedQueue
- LinkedQueue ✔️
- PriorityQueue ✔️
- CircularQueue
- DeQueue ✔️

- stack
Expand Down
87 changes: 87 additions & 0 deletions queues/linked_queue.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package queues

import (
"fmt"
"github.com/246859/containers"
"github.com/246859/containers/lists"
"strings"
)

var _ Deque[any] = (*LinkedQueue[any])(nil)

func NewLinkedQueue[T any]() *LinkedQueue[T] {
return &LinkedQueue[T]{
list: lists.NewLinkedList[T](),
}
}

// LinkedQueue implements the Queue interface and Deque interface.
// It is different from ArrayDeque because it is based on lists.LinkedList,
// so no need to consider capacity of growing and shrinking.
type LinkedQueue[T any] struct {
list *lists.LinkedList[T]
}

func (l *LinkedQueue[T]) Push(es ...T) {
l.list.Add(es...)
}

func (l *LinkedQueue[T]) Peek() (T, bool) {
return l.list.Get(0)
}

func (l *LinkedQueue[T]) Pop() (T, bool) {
val, found := l.list.Get(0)
if !found {
return val, false
}
l.list.Remove(0)
return val, true
}

func (l *LinkedQueue[T]) LPush(es ...T) {
l.list.Insert(0, es...)
}

func (l *LinkedQueue[T]) RPeek() (T, bool) {
return l.list.Get(l.Size() - 1)
}

func (l *LinkedQueue[T]) RPop() (T, bool) {
val, found := l.list.Get(l.Size() - 1)
if !found {
return val, false
}
l.list.Remove(l.Size() - 1)
return val, true
}

func (l *LinkedQueue[T]) Iterator() containers.IndexIterator[T] {
return l.list.Iterator()
}

func (l *LinkedQueue[T]) Values() []T {
return l.list.Values()
}

func (l *LinkedQueue[T]) Size() int {
return l.list.Size()
}

func (l *LinkedQueue[T]) Clear() {
l.list.Clear()
}

func (l *LinkedQueue[T]) String() string {
var b strings.Builder
b.WriteString("LinkedQueue[")
elems := l.Values()
for i, v := range elems {
b.WriteString(fmt.Sprintf("%v", v))
if i != len(elems)-1 {
b.WriteByte(',')
}
}
b.WriteByte(']')
return b.String()
}
85 changes: 85 additions & 0 deletions queues/linked_queue_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package queues

import (
"github.com/stretchr/testify/assert"
"slices"
"testing"
)

func TestLinkedQueue_New(t *testing.T) {
dequeue := NewLinkedQueue[int]()
assert.NotNil(t, dequeue)
}

func TestLinkedQueue_Peek(t *testing.T) {
dequeue := NewLinkedQueue[int]()
// push
dequeue.Push(1)
dequeue.LPush(4)
dequeue.Push(2)
dequeue.LPush(5)

lPeek, b := dequeue.Peek()
assert.True(t, b)
assert.EqualValues(t, 5, lPeek)

rPeek, b2 := dequeue.RPeek()
assert.True(t, b2)
assert.EqualValues(t, 2, rPeek)
}

func TestLinkedQueue_Push(t *testing.T) {
dequeue := NewLinkedQueue[int]()
// push
dequeue.Push(1)
dequeue.LPush(4)
dequeue.Push(2)
dequeue.LPush(5)

t.Log(dequeue.String())

values := dequeue.Values()
expected := []int{5, 4, 1, 2}
assert.EqualValues(t, expected, values)
}

func TestLinkedQueue_Push_Pop(t *testing.T) {
dequeue := NewLinkedQueue[int]()
// push
dequeue.Push(1)
dequeue.LPush(4)
dequeue.Push(2)
dequeue.LPush(5)

t.Log(dequeue.String())

pop1, ok1 := dequeue.Pop()
assert.True(t, ok1)
assert.EqualValues(t, 5, pop1)

pop2, ok2 := dequeue.RPop()
assert.True(t, ok2)
assert.EqualValues(t, 2, pop2)
t.Log(dequeue.Values())
}

func TestNewLinkedQueue_Iterator(t *testing.T) {
dequeue := NewLinkedQueue[int]()
var expectedCount = 1000
var expected []int
for i := 0; i < expectedCount; i++ {
if i%2 == 0 {
expected = append(expected, i)
dequeue.Push(i)
} else {
expected = slices.Insert(expected, 0, i)
dequeue.LPush(i)
}
}
assert.EqualValues(t, expectedCount, dequeue.Size())
assert.EqualValues(t, expected, dequeue.Values())

for it := dequeue.Iterator(); it.Valid(); it.Next() {
assert.EqualValues(t, expected[it.Index()], it.Value())
}
}

0 comments on commit 2025af6

Please sign in to comment.