As data structures go, your situation is not a tree but a graph (more general). The JDK does not have a Graph
data type (nor a Tree
, for that matter) so you have to look to something like JGraphT.
DirectedGraph<Integer, DefaultEdge> g =
SimpleDirectedGraph.<Integer, DefaultEdge> builder(DefaultEdge.class)
.addEdgeChain(1, 3, 5, 7)
.addEdgeChain(1, 3, 5, 9)
.addEdgeChain(1, 3, 6, 9)
.addEdgeChain(1, 3, 6, 8)
.addEdgeChain(1, 2, 6, 9)
.addEdgeChain(1, 2, 6, 8)
.addEdgeChain(1, 2, 4, 8)
.build();
// the edge chains are just to be exhaustive in all the paths
// but only one edge is added, for each pair, like the following
g.addVertex(10);
g.addEdge(8, 10);
Stream<Integer> parents = g.incomingEdgesOf(6).stream().map(g::getEdgeSource);
Stream<Integer> children = g.outgoingEdgesOf(6).stream().map(g::getEdgeTarget);
System.out.println(" parents of 6 = " + parents.collect(Collectors.toList()));
System.out.println("children of 6 = " + children.collect(Collectors.toList()));
You can also used undirected graphs but then you would need to get all edges connecting 6 and check if 6 is the source or the target to get what you want.
There might be an overhead, for your scenario, because JGraphT is very generic. Still it's very convenient and, after the first tries with the API, simple to use.