我正在尝试使用scala实现一个简单的二叉树。 我的树定义如下:
abstract class Tree[T <: Ordered[T]]
case class Node[T <: Ordered[T]](v:T, l:Tree[T], r:Tree[T]) extends Tree[T]
case class Leaf[T <: Ordered[T]](v:T) extends Tree[T]
我正在尝试实现一种方法来查找树中的最小值。方法实现如下:
def minInTree[T <: Ordered[T]](t: Tree[T]): T = t match {
case Node(v, lft, rght) if minInTree(lft) > minInTree(rght) => {
val mLft = minInTree(lft)
val mRght = minInTree(rght)
if (v > mRght)
mRght
else
v
}
case Node(v, lft, rght) if minInTree(lft) <= minInTree(rght) => {
val mLft = minInTree(lft)
val mRght = minInTree(rght)
if (v > mLft)
mLft
else
v
}
case Leaf(lf) => lf
}
我发现minInTree(lft)
和minInTree(rght)
被多次调用,我认为这是缓慢而丑陋的。比较使用多个if-else
子句,我认为这也是丑陋的。
有没有优雅的方法来重组代码? 任何提示都表示赞赏。
答案 0 :(得分:3)
如果您要使用Ordering
类型类,则可以对您的值使用min()
方法,这样可以使事情更加优雅。
abstract class Tree[T: Ordering]
case class Node[T: Ordering](v:T, l:Tree[T], r:Tree[T]) extends Tree[T]
case class Leaf[T: Ordering](v:T) extends Tree[T]
def minInTree[T](t: Tree[T])(implicit ev:Ordering[T]): T = t match {
case Node(v, lft, rght) => ev.min(v, ev.min(minInTree(lft), minInTree(rght)))
case Leaf(lf) => lf
}
导入一些方便的含义,min
评估更清晰。
import Ordering.Implicits._
def minInTree[T: Ordering](t: Tree[T]): T = t match {
case Node(v, lft, rght) => v min minInTree(lft) min minInTree(rght)
case Leaf(lf) => lf
}
它还使基本比较操作可用。 (<
,>
等。)
答案 1 :(得分:2)
我稍后会进行比较,我认为没有一种方法可以实现这一目标:
julia> x = ;date
ERROR: syntax: unexpected ;
julia> x = readstring(`date`)
"Thu Dec 14 21:33:48 PST 2017\n"
julia> x
"Thu Dec 14 21:33:48 PST 2017\n"
答案 2 :(得分:2)
正如jwvh所写,你可以使用Ordering来获得更清晰的代码。 另一种拥有更清晰代码的方法是使用继承代替模式匹配:
println("Welcome to the Scala worksheet") //> Welcome to the Scala worksheet
sealed trait Tree[T] {
def min(implicit ev : Ordering[T]) : T
}
case class Node[T](value : T, left : Tree[T], right : Tree[T]) extends Tree[T] {
def min(implicit ev : Ordering[T]) : T = ev.min(value, ev.min(left.min(ev), right.min(ev)))
}
case class Leaf[T](value : T) extends Tree[T] {
def min(implicit ev : Ordering[T]) : T = value
}
val tree = Node(17, Leaf(2), Node(4, Leaf(10), Leaf(8)))
//> tree : testTree#626615.Node#1020777[Int#918] = Node(17,Leaf(2),Node(4,Leaf(
//| 10),Leaf(8)))
tree.min //> res0: Int#918 = 2
我更喜欢在需要时为min方法添加Ordering类型类。 如果你还想要一个功能,那很简单:
def minTree[T](t : Tree[T])(implicit ev : Ordering[T]) = t.min
minTree(tree) //> res1: Int#918 = 2