Algorithm 如何从已排序的流中最佳地构建持久化二叉树

Algorithm 如何从已排序的流中最佳地构建持久化二叉树,algorithm,scala,binary-tree,persistent-data,Algorithm,Scala,Binary Tree,Persistent Data,对于一个附带项目,我想要一种简单的方法,从排序的流生成一个持久的二进制搜索树。经过一些粗略的搜索,我只能找到有关存储排序数组的技术的描述,您可以通过索引访问任何元素。我最后写了一些有用的东西,但我认为这是一个很好的领域,一个规范的例子可能在某个地方有记录(可能有一个名字) 我制作的makeshift代码只是为了清晰起见。(也很短) 要创建一个平衡树(我猜您会想这么做),您需要至少访问每个节点一次。首先,将所有节点收集到缓冲区中,然后递归地将缓冲区转换为树: def tfs[T](stream

对于一个附带项目,我想要一种简单的方法,从排序的流生成一个持久的二进制搜索树。经过一些粗略的搜索,我只能找到有关存储排序数组的技术的描述,您可以通过索引访问任何元素。我最后写了一些有用的东西,但我认为这是一个很好的领域,一个规范的例子可能在某个地方有记录(可能有一个名字)

我制作的makeshift代码只是为了清晰起见。(也很短)


要创建一个平衡树(我猜您会想这么做),您需要至少访问每个节点一次。首先,将所有节点收集到缓冲区中,然后递归地将缓冲区转换为树:

  def tfs[T](stream: Stream[T]): ImmutableTree[T] = {
    val ss = scala.collection.mutable.ArrayBuffer.empty[T]
    def treeFromSubsequence(start: Int, end: Int): ImmutableTree[T] =
      if (end == start) NilTree()
      else if (end - start == 1) ImmutableTreeNode(ss(start), NilTree(), NilTree())
      else {
        val mid = (end - start) / 2
        ImmutableTreeNode(ss(mid), treeFromSubsequence(start, mid), treeFromSubsequence(mid + 1, end))
      }
    stream.foreach { x => ss += x }
    treeFromSubsequence(0, ss.length)
  }

它将精确地访问每个值两次,一次用于收集,一次用于将其放入树的值字段。

您不需要提前访问所有节点。最简单的例子是a,它有许多类型。可能有一个版本针对有序插入进行了优化。您正在对数组中的所有元素进行随机访问。问题指出,这个答案是在别处找到的,“经过一些粗略的搜索,我只能找到有关存储排序数组的技术描述,您可以通过索引访问任何元素。”问题中提供的代码已经可以通过流来完成这一任务。@JimMischel您能更明确一些吗?哪些实现使用持久化二叉树?@StevenNoble这些实现中没有一个是持久化二叉树,但有几个可以为此目的进行修改。我不是持久性数据结构方面的专家,因此无法提供任何具体细节。我在这里评论的要点是,不要求预先知道节点的数量或节点本身。如果您不能或不愿利用流是有序的或节点的数量可以知道的知识,那么您将有一个
O(N log N)
算法。我介绍的算法是
O(N)
我不读或写scala,所以不会对您的代码发表评论。如果您事先知道节点的数量,则可以在O(n)时间内为长度为n的排序输入生成一个联机。如果您事先不知道输入大小,可以生成一个树,其中根的左子树是完美的,右子树是完整的。如果输入的大小是2^k-1的形式,那么while树将是完美的。该算法将树片段累积在堆栈中,并在新元素到达时将它们缝合在一起。@Gene:我提前不知道大小的情况听起来像是我感兴趣的。你能给我指一个引文吗?你可以看看这篇文章:
  def tfs[T](stream: Stream[T]): ImmutableTree[T] = {
    val ss = scala.collection.mutable.ArrayBuffer.empty[T]
    def treeFromSubsequence(start: Int, end: Int): ImmutableTree[T] =
      if (end == start) NilTree()
      else if (end - start == 1) ImmutableTreeNode(ss(start), NilTree(), NilTree())
      else {
        val mid = (end - start) / 2
        ImmutableTreeNode(ss(mid), treeFromSubsequence(start, mid), treeFromSubsequence(mid + 1, end))
      }
    stream.foreach { x => ss += x }
    treeFromSubsequence(0, ss.length)
  }