Algorithm 生成n数组树中的所有叶到叶路径
给定一个N元树,我必须在一个N元数组树中生成所有叶到叶的路径。路径还应表示方向。例如: 树: 路径:Algorithm 生成n数组树中的所有叶到叶路径,algorithm,tree,depth-first-search,breadth-first-search,tree-traversal,Algorithm,Tree,Depth First Search,Breadth First Search,Tree Traversal,给定一个N元树,我必须在一个N元数组树中生成所有叶到叶的路径。路径还应表示方向。例如: 树: 路径: 5上升3上升2下降4 4上升2上升1下降6 5向上3向上2向上1向下6 这些路径可以是任意顺序,但需要生成所有路径 我看到了一种模式: 看起来我必须按顺序遍历和 需要保存到目前为止我所看到的 然而,我们不能真正想出一个实际的工作算法 有人能告诉我正确的算法吗 我不是在寻找实际的实现,我只希望看到伪代码和概念性的想法。我要做的第一件事是执行顺序遍历。因此,我们将按从最左侧到最右侧节点的顺序
- 5上升3上升2下降4
- 4上升2上升1下降6
- 5向上3向上2向上1向下6
- 看起来我必须按顺序遍历和
- 需要保存到目前为止我所看到的
我不是在寻找实际的实现,我只希望看到伪代码和概念性的想法。我要做的第一件事是执行顺序遍历。因此,我们将按从最左侧到最右侧节点的顺序累积所有叶子。(在您的情况下,这将是
[5,4,6]
)
在此过程中,我肯定会找到节点与其父节点之间的映射,以便我们以后可以执行dfs。我们可以将此映射保存在HashMap
(或其类似项)中。除此之外,我们还需要节点之间的映射及其优先级,我们可以根据顺序遍历的结果进行计算。在您的示例中,顺序为[5,3,2,4,1,6]
,优先级列表分别为[0,1,2,3,4,5]
这里我假设我们的节点看起来像(我们可能事先没有映射节点->父节点):
如果我们有n
叶子,那么我们需要找到n*(n-1)/2
路径。显然,如果我们已经找到了从叶a
到叶B
的路径,那么我们就可以轻松地计算出从B
到a
的路径。(通过向上->向下转换,反之亦然)
然后我们开始遍历前面计算的叶数组。对于数组中的每个叶,我们应该查找到位于当前叶右侧的叶的路径。(因为我们已经找到了从最左侧节点到当前叶的路径)
要执行dfs搜索,我们应该向上搜索,对于遇到的每个节点,检查是否可以转到其子节点。我们不应该去找优先级低于当前叶子优先级的孩子。(这样做将引导我们找到我们已经拥有的路径)除此之外,我们不应该访问沿途已经访问过的节点
当我们从某个节点执行dfs时,我们可以维护一个特定的结构来保留我们到目前为止遇到的节点(例如,StringBuilder
,如果您使用Java编程)。在我们的例子中,如果我们已经从叶5到达叶4,那么我们累积路径=5向上3向上2向下4
。由于我们已经到达一个叶子,我们可以放弃最后访问的节点,继续dfs和路径=5向上3向上2
也许有更先进的技术可以解决这个问题,但我认为这是一个很好的起点。我希望这种方法能帮助您解决问题。如果不使用Python编程,我无法创建解决方案。假设我没有忽略一个角落的案例,我的尝试是这样的: 在深度优先搜索中,每个节点接收向下路径,如果节点是叶子或将向下路径传递给它的子节点,则释放它们(加上本身)。唯一要考虑的是叶节点是向上路径的起点,所以这些是从左到右的输入,以及返回到父节点。
def print_leaf2leaf(root, path_down):
for st in path_down:
st.append(root)
if all([x is None for x in root.children]):
for st in path_down:
for n in st: print(n.d,end=" ")
print()
path_up = [[root]]
else:
path_up = []
for child in root.children:
path_up += child is not None and [st+[root] for st in print_root2root(child, path_down + path_up)] or []
for st in path_down:
st.pop()
return path_up
class node:
def __init__(self,d,*children):
self.d = d
self.children = children
## 1
## / \
## 2 6
## / \ /
## 3 4 7
## / / | \
## 5 8 9 10
five = node(5)
three = node(3,five)
four = node(4)
two = node(2,three,four)
eight = node(8)
nine = node(9)
ten = node(10)
seven = node(7,eight,nine,ten)
six = node(6,None,seven)
one = node(1,two,six)
print_leaf2leaf(one,[])
我想你的意思是“n元”,不是“n数组”?或者我问你关于数组表示的问题?@trincot的意思是n元树,文本更新。你能对我的解决方案发表意见吗?
class TreeNode {
int val;
TreeNode[] nodes;
TreeNode(int x) {
val = x;
}
}
def print_leaf2leaf(root, path_down):
for st in path_down:
st.append(root)
if all([x is None for x in root.children]):
for st in path_down:
for n in st: print(n.d,end=" ")
print()
path_up = [[root]]
else:
path_up = []
for child in root.children:
path_up += child is not None and [st+[root] for st in print_root2root(child, path_down + path_up)] or []
for st in path_down:
st.pop()
return path_up
class node:
def __init__(self,d,*children):
self.d = d
self.children = children
## 1
## / \
## 2 6
## / \ /
## 3 4 7
## / / | \
## 5 8 9 10
five = node(5)
three = node(3,five)
four = node(4)
two = node(2,three,four)
eight = node(8)
nine = node(9)
ten = node(10)
seven = node(7,eight,nine,ten)
six = node(6,None,seven)
one = node(1,two,six)
print_leaf2leaf(one,[])