顺序前,顺序后和顺序中的哪些组合是唯一的?


28

我们知道订单,

post L(x)     => [x]
post N(x,l,r) => (post l) ++ (post r) ++ [x]

和预购

pre L(x)     => [x]
pre N(x,l,r) => [x] ++ (pre l) ++ (pre r)

和有序遍历 顺序化。

in L(x)     => [x]
in N(x,l,r) => (in l) ++ [x] ++ (in r)

即使我们假定成对的不同键/标签,也可以很容易地看出它们都不是唯一描述给定的树。

为此可以使用这三种的哪些组合,哪些不能使用?

肯定的答案应该包括(有效的)算法来重建树,并证明(正确的)原因。否定答案应提供反例,即具有相同表示形式的不同树。

Answers:


16

首先,我假设所有元素都是不同的。序列化的数量不会告诉您带有元素的树的形状[3,3,3,3,3]。当然,可以用重复的元素重建一些树。我不知道有什么好的充分条件。

继续负面结果,您不能仅凭其前序和后序序列完全重建二叉树。[1,2]预购,[2,1]后购必须1是根源,但2可以是左孩子或右孩子。如果您不关心这种歧义性,则可以使用以下算法来重构树:

  • 令为前序遍历,为后序遍历。我们必须具有,这是树的根。[ y ny 1 ] x 1 = y 1[x1,,xn][yn,,y1]x1=y1
  • y 2 x 2 = y 2 [ x 2x n ] [ y ny 2 ]x2是根的最左子,而是根的最右子。如果,则根节点是一元的;在和上以构建单个子树。y2x2=y2[x2,,xn][yn,,y2]
  • 否则,令和为索引,使得和。是左子树的前序遍历,是右子树的前序遍历,类似地,是后序遍历。左子树具有元素,而右子树具有元素。为每个子树递归一次。 顺便说一下,该方法可以推广到具有任意分支的树。使用任意分支,找出左侧子树的范围,并从两个列表中都切掉其元素,然后重复以从左侧切出第二个子树,依此类推。j x 2 = y i y 2 = x j [ x 2x j 1 ] [ x jx n ] j 2 = n i + 1 i 2 = n j + 1 j 2ijx2=yiy2=xj[x2,,xj1][xj,,xn]j2=ni+1i2=nj+1
    j2

如前所述,运行时间为,最差情况为(在有两个孩子的情况下,我们逐行搜索每个列表)。如果对列表进行预处理以构建从元素值到输入列表中位置的有限映射结构,则可以将其转换为。也可以使用数组或有限映射从索引到值。坚持使用全局索引,以便递归调用将接收整个地图,并以范围作为参数来知道要采取的行动。Θ n 2O nO(n2)Θ(n2)nO(nlg(n))nlg(n)

通过预遍历和有序遍历,可以按以下方式重建树:[ z 1z n ][x1,,xn][z1,,zn]

  • 根是预遍历的头。x1
  • 令为使的索引。然后是左子项的有序遍历,是右子项的有序遍历。根据元素的数量,是左子元素的预遍历,是右子元素的预遍历。递归以建立左右子树。z k = x 1 [ z 1z k 1 ] [ z k + 1z n ] [ x 2x k ] [ x k + 1x n ]kzk=x1[z1,,zk1][zk+1,,zn][x2,,xk][xk+1,,xn]

再次,该算法如上所述为,如果将列表预处理为从值到位置的有限映射,则可以在执行。O nO(n2)O(nlg(n))

后订单加订单当然是对称的。


这里是否有错字:“ [1,2]前置,[1,2]后阶必须在根有1个,但2个可以是左子或右子。”这样的后继无论2是左孩子还是右孩子,树都是[2,1]而不是[1,2]。另外,您是说如果同时给出了预购和后购,我们将无法重构该树,还是您仅给出其中之一便无法重构该树?
CEGRD 2012年

@CEGRD确实,邮购是错字。该示例显示,在这种情况下,您无法完全重建树:您不知道2是左子还是右子。这对应于重建算法的“单个子树”情况。
吉尔斯(Gilles)'“ SO-不要邪恶”

如果我们知道它是二进制搜索树,该如何变化?对于您示例中的简单情况([1,2]前置,[2,1]后置),我们将能够确定根为1且2是正确的子代(因为2大于1) ... 对?
fersarr 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.