我有一个树的两个平面表示,例如:
List 1: List 2:
Event1 Event1
Event1 State1
Event2 Event1
State1 Event2
Event2 Event2
Event1 State2
Event2 StateI1
StateI1 Event1
Event1 Event2
Event1 Event1
Event2 StateI2
StateI2 Event1
Event2 Event2
Event1 Event2
Event2 StateI3
StateI3 Event1
State2 Event2
Event3 Event3
树是:
Event1
State1
Event1
Event2
Event2
State2
StateI1
Event1
Event2
Event1
StateI2
Event1
Event2
Event2
StateI3
Event1
Event2
Event3
如您所见,一个国家可以拥有多个事件和国家。不要介意名称,它们不相关,它们只是表示元素的类型。
我相信第一个列表是树的深度优先,自下而上的遍历,第二个列表是深度优先,自上而下的遍历。
我需要从两个平面列表中重新创建树,即将每个State或Event分配给其父状态(或顶层)。这可能吗?如果是这样,怎么样?
我的代码中基本上发生的是:
TraverseTreeBottomUpExecutingFunction(tree, &myfunc_bottomup)
second_list = TraverseTreeTopDown(tree)
recreated_tree = myfunc_recreate_tree(second_list, optional_first_list_created_using_myfunc_bottomup)
我无法更改Traverse *功能。
答案 0 :(得分:2)
基本上不是二叉树的树可以按两个顺序遍历:preorder(在挂起的子树之前枚举内部节点)和postorder(在挂起的子树之后枚举内部节点)。我猜你的问题是“自下而上”是后序,“自上而下”是预购。
让我们进一步假设所有对象可以彼此分离,即它们具有不同的值或指针。如果所有对象都是相同的,即所有对象都是相同的状态,则不能仅从遍历列表中推断出树的形状,因为它们看起来完全相同。
现在的问题是,如果有一个树T,并且预订序和后序遍历为它生成了节点列表,那么该树的ROOT是预订单列表中的FIRST节点和后序列表上的LAST节点。这为您提供了以下重建方法:
您有两个列表,preorder和postorder遍历的节点列表。称这些为R(pRe)和O(pOst)。
伪代码 - 返回树的递归过程。输入:两个遍历列表r = preorder,o = postorder
def mktree(r, o):
l = len(r)
assert l == len(o)
root = r[0]
assert root == o[l - 1]
if l == 1:
return mknode(root)
else:
myroot = mknode(root)
r = r[1:l] # sublist that excludes first element
o = o[0:l-1] # sublist that excludes last element
while len(r) > 0: # iterate and construct subtrees
first = r[0]
lim = -1
for i in 0..l - 1:
if o[i] == first:
lim = i + 1
break
assert lim != -1
myroot.add_rightmost_child(mktree(r[0:lim], o[0:lim])
r = r[lim:len(r)] # sublist from lim until end of list
o = o[lim:len(o)] # sublist from lim until end of list
return myroot
以下是其工作原理的示例:
原树:
1
/ | \
2 3 4
/ / \
5 6 7
预订遍历(“自上而下深度优先”):1 2 5 3 4 6 7
后序遍历(“自下而上”):5 2 3 6 7 4 1
算法执行:
mktree(1253467, 5236741)
myroot = 1
r = 253467, o = 523674
loc = 1 (location of '2' in o)
mktree(25, 52)
myroot = 2
mktree(5, 5) -> returns singleton tree 5
list exhausted -> returns tree 2[5] (5 only child of 2)
add 2[5] to myroot as right child, tree at myroot 1[2[5]]
r = 3467, o = 3674 (stripped away "25" that was processed)
loc = 0 (location of '3' in o)
mktree(3, 3) returns singleton tree 3
add 3 to myroot as right child, tree at myroot 1[2[5], 3]
r = 467, o = 674 (stripped away "3" that was processed)
loc = 2 (location of '4' in o)
mktree(467, 674)
myroot = 4
r = 67, o = 67
(recursive calls return first singleton 6, then 7)
returns tree 4[6,7]
add 4[6,7] to myroot as right child, tree at myroot 1[2[5],3,4[6,7]]
list exhausted, return tree
结果,重建了原始树。
作为参考,这里定义了伪代码中的前序和后序遍历:
def preorder(t):
l = [root_node(t)] # BEFORE recursion = PREorder
for c in t.children(): # in left to right order
l.append(preorder(c))
return l
def postorder(t):
l = []
for c in t.children(): # in left to right order
l.append(postorder(c))
l.append(root_node(t)) # AFTER recursion = POSTorder
return l