微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Scala:从列表创建二叉树

如何解决Scala:从列表创建二叉树

我是 Scala 的完全初学者。所以我的问题可能很愚蠢,请耐心等待。 我有一个二叉树结构的模板:

sealed trait Tree[T]
case class Leaf[T]() extends Tree[T]
case class Node[T](left: Tree[T],data :Int,right Tree[T]) extends Tree[T]

我想编写一个从列表创建二叉树的函数。第一个列表元素是根。分支左侧的所有数据较小,分支右侧的所有数据均较大:

def listToTree[T](list: List[T]): Tree[T] 

我不确定我写错了什么,但我的输出始终只是第一个 List 元素

def setElement(x: Int,tree: Tree[Int]): Tree[Int] = tree match {
    case Node(l,e,r) => Node(l,x,r)
    case Leaf() => new Node(Leaf(),Leaf()) 
}
def listToTree2[T](as: List[Int],tree: Tree[Int],x: Int): Tree[Int] = tree match
{
  case Leaf() => listToTree2(as.tail,setElement(as.head,tree),x)
  case Node(left,right) => if(e < x) {
    right match {
      case Leaf() => listToTree2(as.tail,x)
      case Node(left2,e2,right2) => if( e < e2) listToTree2(as,right,x)
      else listToTree2(as,left,x)
    }
  } else if(e > x) { 
    left match {
      case Leaf() => listToTree2(as.tail,x)
      case Node(left3,e3,right3) => if( e < e3) listToTree2(as,x) else listToTree2(as,x)
    }
  } else {
    listToTree2(as.tail,tree,x)
  }
}


def listToTree[T](as: List[Int]): Tree[Int] =
{
  val tree = new Node(Leaf(),as.head,Leaf())
  listToTree2(as,as.head)
}

所以最终正确的输出应该是这样的:


val list = List(3,2,4,1)
assert(listToTree(list) == Branch(Branch(Branch(Leaf(),1,Leaf()),Leaf()))),3,Branch(Leaf(),Leaf()))

解决方法

你的代码中有一些东西似乎没有多大意义......但更重要的是,你写的东西在我看来是线性的,我很确定你不能构建 BST在线性时间(如果可以的话,你也可以按线性时间排序,这会很酷)。因此,与其尝试调试此代码,不如将其丢弃并重新考虑整个方法。

不幸的是,不可变结构并不能让非线性事物的实现变得特别容易。您可以在这里尝试多种方法。特别是从快速排序中借用了 partition 的想法:

def makeTree(data: List[Int]): Tree[Int] = data match {
   case Nil => Leaf()
   case head :: tail => 
      val (left,right) = tail.partition(_ < head)
      Branch(makeTree(left),head,makeTree(right.filterNot(_ == head)))
}
,

这似乎有效:

sealed trait Tree[+T] extends Product with Serializable
final case class Branch[+T](left: Tree[T],elem: T,right: Tree[T]) extends Tree[T]
final case object Leaf extends Tree[Nothing]

object Tree {
  def addToTree[T : Ordering](tree: Tree[T])(t: T): Tree[T] = {
    import Ordering.Implicits._
    
    tree match {
      case Leaf =>
        Branch(left = Leaf,elem = t,right = Leaf)

      case branch @ Branch(left,elem,right) =>
        if (t <= elem) branch.copy(left = addToTree(tree = left)(t))
        else branch.copy(right = addToTree(tree = right)(t))
    }
  }

  def fromList[T : Ordering](data: List[T]): Tree[T] = {    
    data match {
      case root :: tail =>
        tail.foldLeft(Branch(left = Leaf,elem = root,right = Leaf) : Tree[T]) {
          case (acc,t) =>
            addToTree(acc)(t)
        }
      
      case Nil =>
        Leaf
    }
  }
}

请注意,我将问题分为多个步骤,首先从 List 创建一个 Tree 基本上只是从具有根和然后开始将 List 中的每个元素添加到该基础 Tree
将元素添加到也可以分解为相应地将其添加到Branchleft中。


您可以看到在 Scastie 中运行的代码。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。