Skip to content

Commit 6fb5f44

Browse files
committed
实现 ListPriorityQueue
1 parent d4f6eee commit 6fb5f44

File tree

3 files changed

+124
-3
lines changed

3 files changed

+124
-3
lines changed

README.md

+5-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
# 算法学习
22

3-
- [AlgoCasts](https://algocasts.io/)
4-
- [算法图解](http://www.ituring.com.cn/book/1864)
5-
- [算法(第4版)](http://www.ituring.com.cn/book/875)
3+
- [algocasts](algocasts)[AlgoCasts](https://algocasts.io/)
4+
- [algs4](algs4)[算法(第4版)](http://www.ituring.com.cn/book/875)
5+
- [algs4-scala](algs4-scala):算法(第4版)Scala实现,初始源码来自https://github.com/garyaiki/Scala-Algorithms.git
6+
- [leetcode](leetcode):leetcode 习题
7+
- [algorithm](algorithm):[算法图解](https://www.ituring.com.cn/book/1864)
68
- [算法的乐趣](http://www.ituring.com.cn/book/1605)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
package org.gs.queue
2+
3+
import scala.annotation.tailrec
4+
import scala.reflect.ClassTag
5+
6+
// O(n)
7+
abstract class ListPriorityQueue[T](implicit ord: Ordering[T]) extends Iterable[T] {
8+
import ListPriorityQueue._
9+
10+
private val dummy: Node[T] = Node(null.asInstanceOf[T])
11+
12+
private var n = 0
13+
14+
protected def cmp(nv: T, v: T): Boolean
15+
16+
def enqueue(v: T): Unit = {
17+
@tailrec
18+
def loop(root: Node[T]): Unit = root.next match {
19+
case null => root.next = Node(v)
20+
case node if cmp(node.value, v) =>
21+
if (node.next == null) node.next = Node(v) else loop(node.next)
22+
case node => root.next = Node(v, node)
23+
}
24+
25+
loop(dummy)
26+
n += 1
27+
}
28+
29+
def dequeue: Option[T] = {
30+
if (isEmpty) {
31+
None
32+
} else {
33+
val v = head
34+
dummy.next = dummy.next.next
35+
n -= 1
36+
Some(v)
37+
}
38+
}
39+
40+
override def headOption: Option[T] = Option(dummy.next).map(_.value)
41+
42+
override def head: T = dummy.next.value
43+
44+
override def isEmpty: Boolean = n == 0
45+
46+
override def size: Int = n
47+
48+
override def iterator: Iterator[T] = {
49+
new Iterator[T] {
50+
private var node = dummy.next
51+
override def hasNext: Boolean = node ne null
52+
53+
override def next(): T = {
54+
val value = node.value
55+
node = node.next
56+
value
57+
}
58+
}
59+
}
60+
}
61+
62+
object ListPriorityQueue {
63+
case class Node[T](var value: T, var next: Node[T] = null)
64+
}
65+
66+
class ListMaxPQ[T: ClassTag](elems: T*)(implicit ord: Ordering[T]) extends ListPriorityQueue[T] {
67+
elems.foreach(enqueue)
68+
override protected def cmp(nv: T, v: T): Boolean = ord.gt(nv, v)
69+
}
70+
71+
class ListMinPQ[T: ClassTag](elems: T*)(implicit ord: Ordering[T]) extends ListPriorityQueue[T] {
72+
elems.foreach(enqueue)
73+
override protected def cmp(nv: T, v: T): Boolean = ord.lt(nv, v)
74+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package org.gs.queue
2+
3+
import org.scalatest.matchers.should.Matchers
4+
import org.scalatest.wordspec.AnyWordSpec
5+
6+
class ListPriorityQueueTest extends AnyWordSpec with Matchers {
7+
"Max" should {
8+
"head" in {
9+
val q = new ListMaxPQ[Int]()
10+
q.enqueue(5)
11+
q.head shouldBe 5
12+
}
13+
14+
"enqueue" in {
15+
val q = new ListMaxPQ[Int](7, 5, 3, 7)
16+
q.toList shouldBe List(7, 7, 5, 3)
17+
}
18+
19+
"dequeue" in {
20+
val q = new ListMaxPQ[Int](7, 5, 3, 7)
21+
q.head shouldBe 7
22+
q.dequeue shouldBe Some(7)
23+
q.head shouldBe 7
24+
q.dequeue shouldBe Some(5)
25+
q.head shouldBe 3
26+
}
27+
}
28+
29+
"Min" should {
30+
"head" in {
31+
val q = new ListMaxPQ[Int]()
32+
q.enqueue(5)
33+
q.head shouldBe 5
34+
}
35+
36+
"enqueue" in {
37+
val q = new ListMaxPQ[Int](5, 5, 3, 7)
38+
q.toList shouldBe List(3, 5, 5, 7)
39+
}
40+
41+
"dequeue" in {
42+
val q = new ListMaxPQ[Int](7, 5, 3, 7)
43+
}
44+
}
45+
}

0 commit comments

Comments
 (0)