Исходя из рисунка, предполагая, что ребра вершины расположены в порядке возрастания по узлу, на который они указывают, правильный вывод: 0 1 3 6 2 4 5.
Проблема, с которой вы столкнулись, заключается в том, что вы как бы смешали подход динамического программирования со стеком и итеративный подход с переписывающим циклом for
по всем вершинам. Если у вершины есть ребро к другой вершине, у которой индекс ниже, чем у ее собственного индекса, то она не будет сразу посещать узел и вместо этого прибегнет к стеку; последняя вершина, имеющая первый край непосещенных ребер.
Вы исправляете это, используя только подход динамического программирования, затем зацикливаясь назад по краям, помещая их в стек, если они не посещаются. Это оставит ребро для вершины с наименьшим значением на вершине стека, готовое для посещения на следующей итерации.
Ваш первый цикл поиска по глубине становится:
while (!st.isEmpty()) {
int vertex = st.pop();
if (!visited[vertex]) {
System.out.printf("%d ", vertex);
visited[vertex] = true;
for (int i = numVertices - 1; i >= 0; --i) {
if (edges[vertex][i] == 1 && !visited[i]) {
st.push(i);
}
}
}
}
Таким образом, вы используете только один цикл (ваш while
цикл), который продолжает выталкивать из стека. Когда вершина посещается, она помещает все свои не посещенные и связанные вершины в стек в обратном порядке. Это означает, что следующий из посещаемых вершин (DFS) - это наименьший дочерний элемент вершины. Если вершина посещена и находится глубже в стеке, она просто игнорируется при повторном посещении, как и ее дочерние вершины (они также уже были посещены).
Тогда это можно было бы довольно просто изменить на поиск в первую очередь, сделав стек очередью и добавив вершины в порядке возрастания.