Skip to content

Commit

Permalink
Change implementation of IntListQueue
Browse files Browse the repository at this point in the history
The enqueue/dequeue operations are now O(1).
  • Loading branch information
mrekucci committed Oct 9, 2015
1 parent 00c9f54 commit 4029eb0
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 19 deletions.
55 changes: 38 additions & 17 deletions queues/queue.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,7 @@

package queues

import (
"container/list"
"errors"
)
import "errors"

// ErrType indicates that a value is no of the expected type.
var ErrType = errors.New("queues: unexpected type")
Expand All @@ -25,39 +22,63 @@ type Queue interface {
Len() int
}

type node struct {
data int
next *node
}

// IntListQueue is an implementation of the Queue interface
// for integer values backed by doubly linked list.
// for integer values implemented by circular linked list.
type IntListQueue struct {
l *list.List
head, tail *node
len int
}

// Enqueue inserts e e at the back of the queue.
// Enqueue inserts e element at the back of the queue.
// An error is returned if e is not of type int.
// The time complexity is O(1)
func (q *IntListQueue) Enqueue(e interface{}) error {
if _, ok := e.(int); !ok {
v, ok := e.(int)
if !ok {
return ErrType
}
q.l.PushBack(e)
n := &node{data: v}
if q.head == nil {
q.head = n
n.next = q.head
q.tail = q.head
} else {
q.tail.next = n
n.next = q.head
q.tail = n
}
q.len++
return nil
}

// Dequeue removes and returns the front integer element from this queue.
// The time complexity is O(1)
func (q *IntListQueue) Dequeue() interface{} {
if q.Len() == 0 {
switch q.len {
case 0:
return nil
case 1:
v := q.head.data
q.head = nil
q.tail = nil
q.len = 0
return v
}
return q.l.Remove(q.l.Front())
n := q.head
q.head = n.next
q.tail.next = q.head
n.next = nil // Avoid memory leaks.
q.len--
return n.data
}

// Len returns the length of this queue.
// The time complexity is O(1)
func (q *IntListQueue) Len() int {
return q.l.Len()
}

// NewIntListQueue returns an initialized IntListQueue.
func NewIntListQueue() *IntListQueue {
return &IntListQueue{list.New()}
return q.len
}
4 changes: 2 additions & 2 deletions queues/queue_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ func testQueueInterface(t *testing.T, q Queue, tests []queueTest) error {
if err := q.Enqueue(test.e); err != test.err { // Test enqueue error.
return fmt.Errorf("q.Enqueue(%v) = %v; want %v", test.e, err, test.err)
}
if test.err == nil { // Check len when test doesn't have an error.
if test.err == nil { // Check len when test doesn't expect an error.
enqueued++
if err := checkLength(q, enqueued); err != nil {
return fmt.Errorf("q.Enqueue(%v) got %v", test.e, err)
Expand Down Expand Up @@ -87,7 +87,7 @@ func TestIntListQueue(t *testing.T) {
{maxInt, nil},
{"x", ErrType},
}
if err := testQueueInterface(t, NewIntListQueue(), ifaceTests); err != nil {
if err := testQueueInterface(t, new(IntListQueue), ifaceTests); err != nil {
t.Error(err)
}
}

0 comments on commit 4029eb0

Please sign in to comment.