queue related logic and test

This commit is contained in:
ivan 2018-12-18 21:28:08 +08:00
parent d1acb4e797
commit 2b36d4eb62
8 changed files with 157 additions and 0 deletions

View File

@ -0,0 +1,28 @@
package ch09_queue
import scala.reflect.ClassTag
class ArrayQueue[T: ClassTag](capacity: Int) extends DemoQueue[T] {
var items: Array[T] = new Array[T](capacity)
var head = 0
var tail = 0
override def enqueue(data: T): Unit = {
require(tail < capacity, "queue is full")
items(tail) = data
tail += 1
size += 1
}
override def dequeue(): Option[T] = {
if (head < tail) {
val result = Some(items(head))
head += 1
size -= 1
result
} else {
None
}
}
}

View File

@ -0,0 +1,10 @@
package ch09_queue
trait DemoQueue[T] {
var size = 0
def enqueue(data: T): Unit
def dequeue(): Option[T]
}

View File

@ -0,0 +1,19 @@
package ch09_queue
import scala.reflect.ClassTag
class DynamicArrayQueue[T: ClassTag](val capacity: Int) extends ArrayQueue[T](capacity) {
override def enqueue(data: T): Unit = {
if (tail == capacity) {
//tail is the end of
require(head > 0, "queue is full")
for (i <- Range(head, tail)) {
items(i - head) = items(head)
}
tail = tail - head
head = 0
}
super.enqueue(data)
}
}

View File

@ -0,0 +1,39 @@
package ch09_queue
class Node[T](var data: T, var next: Option[Node[T]])
class LinkListQueue[T]() extends DemoQueue[T] {
var headOpt: Option[Node[T]] = None
var tailOpt: Option[Node[T]] = None
override
def enqueue(data: T): Unit = {
val node = new Node(data, None)
size += 1
headOpt match {
case None => headOpt = Some(node)
case Some(_) =>
}
tailOpt match {
case None => tailOpt = Some(node)
case Some(tail) =>
tail.next = Some(node)
tailOpt = Some(node)
}
}
override
def dequeue(): Option[T] = {
headOpt.map(head => {
size -= 1
headOpt = head.next
if (headOpt.isEmpty) {
//head is empty reach the end of the queue
tailOpt = None
}
head.data
})
}
}

View File

@ -0,0 +1,6 @@
package ch09_queue
class ArrayQueueTest extends DemoQueueTest {
override def getInstance() = new ArrayQueue[Int](15)
}

View File

@ -0,0 +1,28 @@
package ch09_queue
import org.scalatest.{FlatSpec, Matchers}
abstract class DemoQueueTest extends FlatSpec with Matchers {
def getInstance(): DemoQueue[Int]
behavior of "test"
it should "dequeue nothing for empty queue" in {
val queue = getInstance()
assert(queue.dequeue().isEmpty)
}
it should "enqueue/dequeue should be FIFO" in {
val queue = getInstance()
for (i <- Range(0, 10)) {
queue.enqueue(i)
}
queue.size should equal(10)
for (i <- Range(0, 10)) {
queue.dequeue().get should equal(i)
}
}
}

View File

@ -0,0 +1,20 @@
package ch09_queue
class DynamicArrayQueueTest extends DemoQueueTest {
override def getInstance(): DemoQueue[Int] = new DynamicArrayQueue[Int](15)
it should "copy data when tail reach the end of the queue" in {
val queue = getInstance()
for (i <- Range(0, 15)) {
queue.enqueue(i)
}
queue.size should equal(15)
queue.dequeue().get should equal(0)
//enqueue another one
queue.enqueue(30)
queue.size should equal(15)
}
}

View File

@ -0,0 +1,7 @@
package ch09_queue
class LinkedListQueueTest extends DemoQueueTest {
override def getInstance() = new LinkListQueue[Int]
}