Вы правы, говоря, что узел 1
снова будет помещен в стек. Но это не имеет значения: в основном оно будет проигнорировано на следующем проходе, потому что оно уже помечено как «посещенное»:
if (current is in visited):
continue
Кроме того, вы можете добавить узел в стек только в том случае, если он еще не посещен:
for each node v such that (current,v) is an edge:
if (v is NOT in visited) s.push(v)
Не исключено, что вы добавите эту проверку в практическую реализацию. Но код является псевдокодом, и он часто пишется в очень общей форме, где такого рода «оптимизация» или «улучшение» не учитывается ради компактности и универсальности, если алгоритм верен. И здесь разница не влияет на правильность: в обоих случаях та часть, которая говорит
// do something with current
будет выполняться только один раз для каждого узла.