Изменить: Этот ответ совершенно не по теме и был опубликован из-за неправильного толкования вопроса.
В реализации DFS есть несколько ошибок. Да, он посещает все узлы в глубине и в конечном итоге ему удается найти путь между START и END, но он не пытается проверять уже посещенные узлы и сохраняет стек без какой-либо реальной причины. Единственная причина, по которой вы не впадаете в бесконечную рекурсию циклов, заключается в том, что вы ограничиваете максимальную длину пути, и вам все равно потребуется много времени на графах, которые имеют несколько различных путей между всеми парами вершин.
Единственное, для чего вы используете стек - это пропуск узла, который вы хотите посетить, рядом с функцией dfs. Вы можете просто избавиться от стека и передать узел напрямую.
Итак, вместо
private void depthFirst(WeightedDirectedGraph graph, Stack<String> visited) {
...
visited.push(child);
...
depthFirst(graph, visited);
Вы можете просто написать это как
private void depthFirst(WeightedDirectedGraph graph, String node) {
...
//visited.push(child); <-- No longer needed
...
depthFirst(graph, child);
Вы используете структуру данных (стек), которую вы назвали «посещенной», и тем не менее вы не используете ее для хранения / пометки, какие узлы уже были посещены, чтобы избежать повторного посещения.
Вы можете изменить свой существующий код, чтобы он называл Set посещенным (сделайте его глобальной переменной или переменной класса или передайте его через рекурсивные вызовы, как вы делали со своим стеком), где вы сохраняете все уже посещенные узлы и вызываете только deepFirst () те узлы, которых еще нет в этом наборе.
Это должно заставить ваш код выглядеть примерно так
private void depthFirst(WeightedDirectedGraph graph, String node, Set<String> visited) {
visited.add(node); // mark current node as visited
...
//visited.push(child); <-- No longer needed
...
if (!visited.contains(child)){ // don't visit nodes we have worked on already
depthFirst(graph, child);
}
Пока что мой ответ - попытаться изменить ваш код, чтобы он работал. Но мне кажется, что вам нужно лучше понять, что такое DFS и как она работает на самом деле. Чтение соответствующей главы о любой хорошей книге «Алгоритм / Теория графиков» очень вам поможет. Я бы порекомендовал CLRS (там есть очень хорошая глава о простых обходах графов), но подойдет любая хорошая книга. Простой и правильный рекурсивный DFS может быть реализован намного проще с использованием массивов, без необходимости прибегать к стекам или наборам.
Edit:
Я не упомянул, как можно получить путь после замены стека. Это можно легко сделать с помощью карты, в которой хранится родительский элемент каждого узла при его исследовании. Путь (если он найден) можно получить с помощью рекурсивной функции printPath (String node), которая печатает переданный ему узел и снова вызывает себя у его родителя.