我有一个属于树的节点列表。我只想将列表过滤到最低的孩子。对于示例树:
(1)
|
+-- (2)
|
+-- (3)
|
+-- (4)
|
+-- (5)
|
+--(6)
如果我的列表为[1,2,5,6]
,则我希望结果为[2,6]
,因为它们是后代中最低的。
我有一个节点方法is_descendant()
,它有两个节点,并返回True
或False
。
例如:
1.is_descendant(2) ---> False
2.is_descendant(1) ---> True
6.is_descendant(1) ---> True
我的第一个想法是从列表中的第一个元素开始,并将is_descendant()
方法应用于所有其他元素。每当它返回True
时,我都会从列表中删除其他项-因为它是父节点。
有没有更有效的方法?还是这种方法会在100%的时间内有效(可能吗?)
答案 0 :(得分:1)
规则似乎是,如果节点在列表中,并且其任何后代都在列表中,则应从列表中删除该节点。可以使用相当简单的递归函数来实现。
一些需要说明的Java代码:
static <E> boolean descendentsIn(Node<E> node, Set<E> nodes)
{
boolean descendentsIn = false;
for(Node<E> n : node.children)
{
if(descendentsIn(n, nodes) || nodes.contains(n.e))
descendentsIn = true;
}
if(descendentsIn && nodes.contains(node.e))
nodes.remove(node.e);
return descendentsIn;
}
static class Node<E>
{
E e;
List<Node<E>> children = new ArrayList<>();
public Node(E e)
{
this.e = e;
}
}
测试:
public static void main(String[] args)
{
Node<Integer> root = new Node<>(1);
root.children.add(new Node<>(2));
root.children.add(new Node<>(3));
root.children.get(1).children.add(new Node<>(4));
root.children.get(1).children.add(new Node<>(5));
root.children.get(1).children.get(1).children.add(new Node<>(6));
Set<Integer> nodes = new HashSet<>(Arrays.asList(1, 2, 5, 6));
System.out.println("Before: " + nodes);
descendentsIn(root, nodes);
System.out.println("After: " + nodes);
}
输出:
Before: [1, 2, 5, 6]
After: [2, 6]