我想知道如何最好地实现树数据结构,以便能够枚举所有级别的路径。让我用下面的例子解释一下:
A
/ \
B C
| /\
D E F
我希望能够生成以下内容:
A
B
C
D
E
F
A-B
A-C
B-D
C-E
C-F
A-B-D
A-C-E
A-C-F
截至目前,我正在对使用字典构建的数据结构执行深度优先搜索,并记录可见的唯一节点,但我想知道是否有更好的方法来执行此类操作遍历。有什么建议吗?
答案 0 :(得分:7)
每当你在树上发现问题时,只需使用递归:D
def paths(tree):
#Helper function
#receives a tree and
#returns all paths that have this node as root and all other paths
if tree is the empty tree:
return ([], [])
else: #tree is a node
root = tree.value
rooted_paths = [[root]]
unrooted_paths = []
for subtree in tree.children:
(useable, unueseable) = paths(subtree)
for path in useable:
unrooted_paths.append(path)
rooted_paths.append([root]+path)
for path in unuseable:
unrooted_paths.append(path)
return (rooted_paths, unrooted_paths)
def the_function_you_use_in_the_end(tree):
a,b = paths(tree)
return a+b
答案 1 :(得分:0)
使用深度优先搜索找到树的每个节点的路径,然后调用enumerate-paths(Path p)
,其中p
是从根到节点的路径。我们假设路径p
是一个节点数组p[0] [1] .. p[n]
,其中p[0]
是根,p[n]
是当前节点。
enumerate-paths(p) {
for i = 0 .. n
output p[n - i] .. p[n] as a path.
}
这些路径中的每一个都是不同的,并且每个路径都不同于从树的任何其他节点返回的结果,因为p[n]
中没有其他路径结束。显然它是完整的,因为任何路径都是从节点到它与根之间的某个节点。它也是最佳的,因为它只找到并输出每个路径一次。
订单与您的订单略有不同,但您始终可以创建一个路径列表数组,其中A[x]
是长度为x
的路径列表。然后你可以按照它们的长度顺序输出路径,尽管这需要O(n)存储。
答案 2 :(得分:0)
再多一点:
树中没有重复的每条路径都是由它的开始和结束唯一描述的。
因此枚举路径的一种方法是枚举每对可能的顶点。对于每一对,找到路径相对容易(找到共同的祖先并通过它)。