List<ClassWrapperNode> (List<ClassWrapperNode> roots) { List<ClassWrapperNode> res = new ArrayList<>(); LinkedList<ClassWrapperNode> stackNode = new LinkedList<>(); LinkedList<Integer> stackIndex = new LinkedList<>(); Set<ClassWrapperNode> setVisited = new HashSet<>(); for (ClassWrapperNode root : roots) { stackNode.add(root); stackIndex.add(0); } while (!stackNode.isEmpty()) { ClassWrapperNode node = stackNode.getLast(); int index = stackIndex.removeLast(); setVisited.add(node); List<ClassWrapperNode> lstSubs = node.getSubclasses(); for (; index < lstSubs.size(); index++) { ClassWrapperNode sub = lstSubs.get(index); if (!setVisited.contains(sub)) { stackIndex.add(index + 1); stackNode.add(sub); stackIndex.add(0); break; } } if (index == lstSubs.size()) { res.add(0, node); stackNode.removeLast(); } } return res; }