【问题标题】:How to implement 'find' method for this Btree implementation如何为此 Btree 实现实现“查找”方法
【发布时间】:2018-08-24 05:13:12
【问题描述】:

所以我正在学习 Scala。这是所有节点和 BTree 的基类

abstract sealed class Node[T](implicit val ord : Ordering[T])

abstract sealed class BTree[T](implicit ord : Ordering[T])
extends Node[T] {
def size : Int
def depth : Int

这是基本情况类

object BTree {
//empty node
final case class EmptyNode[T]()(implicit ord : Ordering[T])
  extends BTree[T] {
val size : Int = 0
val depth : Int = 0
}
//node with 1 child
final case class OneNode[T](t : BTree[T])(implicit ord : Ordering[T])
  extends Node[T] {
val size : Int = t.size
val depth : Int = t.depth + 1
}
//node with 2 children
final case class TwoNode[T](t1 : BTree[T], u1 : T, t2 : BTree[T])
                      (implicit ord : Ordering[T]) extends BTree[T] {
val size : Int = t1.size + t2.size + 1
val depth : Int = max(t1.depth, t2.depth) + 1
}

他们继续ThreeNodeFourNode的模式

现在在BTree 类中,我必须实现一个查找功能

//return `Some` of entry if equivalent is found, None if not. 
def find(v : T) : Option[T] = 

而且我无法将我的头包裹在我需要做的事情上。在 Java 中,我只会循环遍历每个节点或其他任何东西,但 Scala 我不知道。甚至Some 的事情。返回的只是Some(v)吗?无论如何,这是我能想到的

//return `Some` of entry if equivalent is found, None if not. 
def find(v : T) : Option[T] = 
this match {

  case EmptyNode() => None

  case TwoNode(EmptyNode(), u1, EmptyNode()) if (v equiv u1) =>
    Some(v)

  case TwoNode(t1, u1, t2) if (v equiv u1) =>
    Some(v)

我不知道在这些情况下该怎么做:

  case TwoNode(t1, u1, t2) if (v < u1) => 

  case TwoNode(t1, u1, t2) if (u1 < v) => 

条目可能在树的下方。

ThreeNode我也有类似情况

  case ThreeNode(EmptyNode(), u1, EmptyNode(), u2, EmptyNode()) if (v equiv u1) =>
    Some(v)
  case ThreeNode(EmptyNode(), u1, EmptyNode(), u2, EmptyNode()) if (v equiv u2) =>
    Some(v)

  case ThreeNode(t1, u1, t2, u2, t3) if (v equiv u1) =>
    Some(v)
  case ThreeNode(t1, u1, t2, u2, t3) if (v equiv u2) =>
    Some(v)

但是再一次,如果 v 位于树的下方,我不知道该怎么办。

   case ThreeNode(t1, u1, t2, u2, t3) if (v < u1) =>

   case ThreeNode(t1, u1, t2, u2, t3) if (u1 < v  && v < u2) =>

   case ThreeNode(t1, u1, t2, u2, t3) if (u2 < v) =>

我也不确定在找到 Some(v) 时是否正确。

任何帮助表示赞赏。谢谢

【问题讨论】:

    标签: scala b-tree


    【解决方案1】:

    您需要使用递归find 方法,如下所示:

      def find(v: T): Boolean =
        this match {
          case OneNode(t1, u1) =>
            (u1 == v) || t1.find(v)
          case TwoNode(t1, u1, t2) =>
            (u1 == v) || t1.find(v) || t2.find(v)
          case _ => false
        }
    

    此版本返回Boolean,因为该值要么存在,要么不存在。如果要返回值所在的节点,则需要返回Option[BTree[T]],逻辑变得更加复杂:

      def findNode(v: T): Option[BTree[T]] =
        this match {
          case OneNode(t1, u1) =>
            if (u1 == v) {
              Some(this)
            } else {
              t1.findNode(v)
            }
          case TwoNode(t1, u1, t2) =>
            if (u1 == v) {
              Some(this)
            } else {
              t1.findNode(v) orElse t2.findNode(v)
            }
          case _ => None
        }
    

    如果有 4 个节点,这将变得笨拙,因此我建议您使用 List[BTree[T]] 而不是枚举子节点。这将使代码更清晰。

    另请注意,您需要将u1 成员添加到OneNode,并且它应该继承自BTree[T] 而不是Node[T],否则您将无法将其添加到其他节点。

    【讨论】:

      猜你喜欢
      • 2011-05-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-28
      • 1970-01-01
      • 2022-01-16
      • 2015-03-20
      • 1970-01-01
      相关资源
      最近更新 更多