Scalaで優先度付きキュー
30分プログラム、その511。Scalaで優先度付きキューを作ってみよう。
wikipedia:優先度つきキューによると、連想リストとキューを組合せるのが一番楽らしいので、それをそのままScalaに落し込んでやる。
ちなみに、Scala Standard Library 2.12.8 - scala.collection.mutable.PriorityQueueというクラスがあるのは知っている。
使い方
val q1 = PriorityQueue[Int]() val q2 = q1.enqueue(0,1).enqueue(0,2).enqueue(-1,3) // 3が一番、優先度が高い val (x,q3) = q2.dequeue // x = 3 // あとは入れた順にでてくる val (y,q4) = q3.dequeue // y = 1 val (z,q5) = q4.dequeue // z = 2
ソースコード
import scala.collection.immutable._ class PriorityQueue[T](map : Map[Int,Queue[T]]){ def enqueue(n : Int,v : T) : PriorityQueue[T] = { val queue = map(n).enqueue(v) val newMap = map + (n -> queue) new PriorityQueue(newMap) } def dequeue() : (T,PriorityQueue[T]) = { val n = map.keys.toList.sort(_ < _).head val (value,queue) = map(n).dequeue val newMap = if(queue.isEmpty){ map - n }else{ map + (n -> queue) } (value,new PriorityQueue(newMap)) } } object PriorityQueue { def apply[T]() : PriorityQueue[T] = { val empty = new Queue[T] new PriorityQueue[T](Map[Int,Queue[T]]() withDefaultValue empty) } } val q1 = PriorityQueue[Int]() val q2 = q1.enqueue(0,1).enqueue(0,2).enqueue(-1,3) val (x,q3) = q2.dequeue // x = 3 val (y,q4) = q3.dequeue // y = 1 val (z,q5) = q4.dequeue // z = 2