他の人が述べたように、オブジェクトのハッシュテーブル/マップをそれらの (直接の) 子のリストに構築します。
そこから、「ターゲット オブジェクト」の直接の子のリストを簡単に検索し、リスト内の各オブジェクトに対してプロセスを繰り返すことができます。
これは、再帰の代わりにキューを使用して、Javaでジェネリックを使用してそれを行った方法です。
public static Set<Node> findDescendants(List<Node> allNodes, Node thisNode) {
// keep a map of Nodes to a List of that Node's direct children
Map<Node, List<Node>> map = new HashMap<Node, List<Node>>();
// populate the map - this is O(n) since we examine each and every node
// in the list
for (Node n : allNodes) {
Node parent = n.getParent();
if (parent != null) {
List<Node> children = map.get(parent);
if (children == null) {
// instantiate list
children = new ArrayList<Node>();
map.put(parent, children);
}
children.add(n);
}
}
// now, create a collection of thisNode's children (of all levels)
Set<Node> allChildren = new HashSet<Node>();
// keep a "queue" of nodes to look at
List<Node> nodesToExamine = new ArrayList<Node>();
nodesToExamine.add(thisNode);
while (nodesToExamine.isEmpty() == false) {
// pop a node off the queue
Node node = nodesToExamine.remove(0);
List<Node> children = map.get(node);
if (children != null) {
for (Node c : children) {
allChildren.add(c);
nodesToExamine.add(c);
}
}
}
return allChildren;
}
予想される実行時間は、正しい計算方法を覚えていれば、O(n) から O(2n) の間です。リスト内のすべてのノードに加えて、ノードのすべての子孫を見つけるためのいくつかの操作が保証されます。最悪の場合 (ルート ノードでアルゴリズムを実行する場合)、すべてのノードが表示されます。リストを2回。