如何在树中识别根节点和所有的子节点
在Stackoverflow上看到了这个问题:Identifying root parents and all their children in trees——如何在树中识别根节点和所有的子节点
问题
如下,有这样的一个树:(原问题是一个pandas dataframe)
1 | parent child parent_level child_level |
它表示的树是这样的:
1 | A X |
如何将这个树表示为:
1 | root children |
解决办法
方便起见,我们把上面的数据表示为一个数组
1 | # parent child parent_level child_level |
递归
一个简单的思路就是我们先找到所有子节点的父节点,可以用一个字典来表示,因此,data
可以表示为{'B': {'A'}, 'C': {'B'}, 'D': {'B', 'X'}, 'Y': {'X'}, 'Z': {'Y'}}
。
然后再通过递归的方式,查看每个子节点的父节点是否在这个字典里
- 若在,说明该父节点还有父节点,则继续递归查找
- 若不再,说明该父节点已经是根节点,结束
Python代码如下:
1 | data = [['A', 'B', 0, 1], |
当然,我们也可以把find_root
改写为生成器
1 | def find_root(tree, child): |
也可以把递归改为栈,来避免递归深度的问题,可以使用 “stack of iterators” pattern
1 | def find_root(tree, child): |
关于for…else见此
利用第三方库:networkx
因为这是一个图问题,所以也可以使用networkx来解决这个问题,特别是 descendants(G, source)函数,可以返回有向无环图中的所有可以达到的节点,对于这个问题,就是可以获得所有可以到达根节点的子节点。
1 | import networkx as nx |