Graph implements Serializable { public Node<T> findRootNode(Node<T> startNode) { List<Node<T>> ascendingNodes = getAscendingNodes(startNode); for (Node<T> node : ascendingNodes) { if(rootNodes.contains(node)) return node; } return null; } Graph(); List<Node<T>> getDescendingNodes(Node<T> node); List<T> getNodesByDFSSearch(); List<Node<T>> nodesAffectedByRemoval(Node<T> node); boolean hasCycle(); Node<T> addNode(T object); void addEdge(T startObject, T endObject); Node<T> findRootNode(Node<T> startNode); boolean removeNode(T object); Node<T> findNode(T object); ArrayList<Node<T>> getNodes(); ArrayList<Node<T>> getRootNodes(); @Override String toString();  }
@Test public void testFindRootNode() throws NodeNotExistsExeption{ Graph<String> graph = new Graph<String>(); graph.addNode("n1"); graph.addNode("n2"); graph.addNode("n3"); graph.addNode("n4"); graph.addNode("n5"); graph.addNode("n6"); graph.addEdge("n2", "n3"); graph.addEdge("n3", "n4"); graph.addEdge("n1", "n5"); graph.addEdge("n2", "n6"); assertEquals(graph.findRootNode(graph.findNode("n5")), graph.findNode("n1")); assertEquals(graph.findRootNode(graph.findNode("n1")), graph.findNode("n1")); assertNotSame(graph.findRootNode(graph.findNode("n1")), graph.findNode("n5")); assertEquals(graph.findRootNode(graph.findNode("n4")), graph.findNode("n2")); }