queue related logic and test
This commit is contained in:
parent
d1acb4e797
commit
2b36d4eb62
28
scala/src/main/scala/ch09_queue/ArrayQueue.scala
Normal file
28
scala/src/main/scala/ch09_queue/ArrayQueue.scala
Normal 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
|
||||
}
|
||||
}
|
||||
}
|
10
scala/src/main/scala/ch09_queue/DemoQueue.scala
Normal file
10
scala/src/main/scala/ch09_queue/DemoQueue.scala
Normal file
@ -0,0 +1,10 @@
|
||||
package ch09_queue
|
||||
|
||||
trait DemoQueue[T] {
|
||||
|
||||
var size = 0
|
||||
|
||||
def enqueue(data: T): Unit
|
||||
|
||||
def dequeue(): Option[T]
|
||||
}
|
19
scala/src/main/scala/ch09_queue/DynamicArrayQueue.scala
Normal file
19
scala/src/main/scala/ch09_queue/DynamicArrayQueue.scala
Normal 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)
|
||||
}
|
||||
}
|
39
scala/src/main/scala/ch09_queue/LinkedListQueue.scala
Normal file
39
scala/src/main/scala/ch09_queue/LinkedListQueue.scala
Normal 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
|
||||
})
|
||||
}
|
||||
|
||||
}
|
6
scala/src/test/scala/ch09_queue/ArrayQueueTest.scala
Normal file
6
scala/src/test/scala/ch09_queue/ArrayQueueTest.scala
Normal file
@ -0,0 +1,6 @@
|
||||
package ch09_queue
|
||||
|
||||
class ArrayQueueTest extends DemoQueueTest {
|
||||
|
||||
override def getInstance() = new ArrayQueue[Int](15)
|
||||
}
|
28
scala/src/test/scala/ch09_queue/DemoQueueTest.scala
Normal file
28
scala/src/test/scala/ch09_queue/DemoQueueTest.scala
Normal 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)
|
||||
}
|
||||
}
|
||||
}
|
20
scala/src/test/scala/ch09_queue/DynamicArrayQueueTest.scala
Normal file
20
scala/src/test/scala/ch09_queue/DynamicArrayQueueTest.scala
Normal 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)
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
package ch09_queue
|
||||
|
||||
class LinkedListQueueTest extends DemoQueueTest {
|
||||
|
||||
override def getInstance() = new LinkListQueue[Int]
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user