【问题标题】:Construct a Tree构造一棵树
【发布时间】:2010-02-04 00:59:44
【问题描述】:

在给定中序和前序遍历的情况下,如何构造一棵树? 我只是在寻找一种有效的算法。

【问题讨论】:

  • 嗯,递归。我希望你不是我的学生。
  • 需要澄清一下。输入数据的格式是什么?树平衡了吗?你所说的高效是什么意思(Ordo(x),或者只是“不是非常疯狂”)。您要构建的结构是什么?树作为链接对象,或使用数组的树。
  • 我是一名毕业生。所以,没有人是学生了:)

标签: algorithm data-structures tree traversal


【解决方案1】:

来自Sun's (Oracle now, I guess...) forum的公然复制和粘贴:

问题:
任何人都可以帮助我了解如何从中序和后序遍历构造二叉树,我只想知道算法以便我可以应用它。 em>

答案:
p_1p_2...p_n 为后序遍历,i_1i_2...i_n 为中序遍历。从后序遍历我们知道树的根是p_n。在中序遍历中找到这个元素,比如i_1i_2...i_k-1p_ni_k+1...i_n。通过中序遍历我们找到左子树中的所有元素,即i_1i_2...i_k-1和右子树中的所有元素,即i_k+1...i_n

删除元素p_n(和元素i_k==p_n)。在p_1p_2...p_j...p_n-1中找到最右边的元素p_j,其中p_ji_1中的一个元素,i_2....@98这是原始树的左子树的根。 Split p_1, p_2 ... p_j and p_j+1 ... p_n-1 and i_1, i_2 ... i_k-1 and i_k+1 ... i_n.现在你有两个子序列代表原始的两个子树的后序和中序遍历 树。

作者:JosAH

我已经按照 Jos 的指示实现了一次算法,并且效果很好!

【讨论】:

  • 在 p_1~p_n-1 中找到最右边的元素 p_j 太耗时了,同时它也在 i_1~i_k-1 中。它需要 O(n^2) 时间。实际上,去掉p_n后,找到它在i_1~i_n中的位置。我们已经知道 p_j 的位置。这是因为我们已经知道了它的左右子树的节点数,可以通过计算i_1~i_n中p_n之后的元素得到。这样,我们就可以很容易地找到分割p_1~p_n-1的地方
【解决方案2】:

由于这是作业,我不会给你一个完整的答案,但希望足以让你感动。

想象一下你有先序遍历,比如this树。

遍历给你 2-7-2-6-5-11-5 ... 等等。注意 5 实际上是根的右孩子。

很明显,你不能仅仅看数字就知道,所以要么你会被告知树的结构,要么你需要存储一些额外的数据(即,a 节点是否是左子节点或右孩子,例如)。

解析树只是一个递归函数,它将前序遍历作为输入(在传递输入时考虑您的范围)。正如我之前提到的,您的预购遍历应该附加一些额外的数据。


效率:

考虑构建这棵树时每个节点被访问了多少次,还要考虑读取输入的操作。有没有办法比构建树更快地重新组织输入?如果您需要操作数据,您必须使用什么结构。


按顺序:您将需要相同的想法来完成它,所以我不会介绍它。如果您迫切需要,我相信其他人会这样做。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-10-24
    • 2021-05-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-27
    • 2021-08-06
    • 1970-01-01
    相关资源
    最近更新 更多