给定树:我们希望支持在节点之间查找路径,同时找到特定节点的子节点
1
/ \
2 3
/ \ \
4 6 5
/
7
在两个节点之间查找路径的有效数据结构是什么 4 - > 5(路径是4 2 1 3 5)
我认为我可以将其建模为相邻列表,然后执行简单的BFS
但同时我们也想维护节点的顺序,因为我们将对类型进行查询 打印节点2的所有子节点......答案是4,6,7
我必须存储父母分数吗? 我觉得我错过了一个重要的数据结构,会不会集合帮助吗? 任何指针或对CLRS的引用,算法设计手册,在线资源都会有所帮助,谢谢
答案 0 :(得分:3)
树上两个顶点之间的每条路径都经过它们的最低共同祖先(LCA),这是该路径上最接近根的唯一顶点。有一种有效的数据结构可以在恒定时间内查询LCA,但它们需要一些工作才能实现。如果你确实实现了它们,那么依次从两个给定顶点x和y中的每一个开始,你可以简单地向上走回树,直到你通过调用lca(x,y)来到达已经识别的顶点。
如果您不想实现这些数据结构,并且可以容忍与树的深度(通常是这种情况)成比例的运行时和内存使用,您可以做同样的事情,但是在每种情况下一直向后走到根,在进入相应列表时存储顶点(一个列表用于x,一个列表用于y)。到达根目录后,通过考虑每个列表的最后一项,然后是每个列表的倒数第二项等,以相反的顺序处理这些列表,寻找第一对不同的顶点(或者go"回到其中一个列表的开头":前一个顶点是LCA。
为了在每个节点中存储子节点,除了父指针之外,只需使用通常的表示。
[编辑:正如Peter de Rivaz所指出的,如果您知道两个顶点的深度,那么您可以获得相同的时间复杂度而不使用LCA数据结构,就像您使用它们一样:只需从较深的顶点向上走,直到它们都处于同一水平,然后平行向上走,直到你碰到一个相同的顶点。这样可以避免一直到根。]