对于一个辅助项目,我想要一种简单的方法来从排序的流中生成持久的二叉搜索树。经过一些粗略的搜索后,我只能找到涉及存储排序数组的技术描述,您可以在其中通过索引访问任何元素。我最终写了一些有用的东西,但我认为这是一个很好的领域,一个规范的例子可能记录在某个地方(并且可能有一个名字)。
为了清楚起见,我制作的 make shift 代码被包含在内。(也很短)
object TreeFromStream {
sealed trait ImmutableTree[T] {
def height: Int
}
case class ImmutableTreeNode[T](
value: T,
left: ImmutableTree[T],
right: ImmutableTree[T]
) extends ImmutableTree[T] {
lazy val height = left.height + 1
}
case class NilTree[T]() extends ImmutableTree[T] {
def height = 0
}
@tailrec
def treeFromStream[T](
stream: Stream[T],
tree: ImmutableTree[T] = NilTree[T](),
ancestors: List[ImmutableTreeNode[T]] = Nil
): ImmutableTree[T] = {
(stream, ancestors) match {
case (Stream.Empty, _) =>
ancestors.foldLeft(tree) { case(right, root) => root.copy(right=right) }
case (_, ancestor :: nextAncestors) if ancestor.left.height == tree.height =>
treeFromStream(stream, ancestor.copy(right=tree), nextAncestors)
case (next #:: rest, _) =>
treeFromStream(
rest, NilTree(),
ImmutableTreeNode(next, tree, NilTree()) :: ancestors
)
}
}
}