package pro;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
public class DFS {
private static int INF = 100; // 点的最大个数
// 邻接链表,存储边的变量容器
private static ArrayList<Integer>[] arrayLists = new ArrayList[INF];
// 控制访问的标记变量
private static boolean[] visited = new boolean[INF];
// 传统递归的深度优先搜素
// 递归遍历
private static void dfs(int cur) {
visited[cur] = true; // 访问到置为true
for (int i = 0; i < arrayLists[cur].size(); i++) {
//寻找下一个没有访问的连接的点。
if(!visited[arrayLists[cur].get(i)]) {
System.out.print(arrayLists[cur].get(i)+" ");
dfs(arrayLists[cur].get(i));
//回溯了继续循环寻找兄弟节点没有访问的连接的点
}
}
}
// 不用递归实现深度优先搜素。模仿stack的方式实现
// 因为Stack的线程安全所以用LinkedList代替效率会好一些
private static LinkedList<int[]> linkedList = new LinkedList<>();
private static void dfs_stack(int start) {
int order = -1, i;
//初始化遍历值
Arrays.fill(visited, false);
linkedList.clear();
visited[start] = true;
// 每次添加元素从最后加入
linkedList.addLast(new int[]{start, -1});
while (!linkedList.isEmpty()) {
int cur = linkedList.getLast()[0];
for (i = order+1; i < arrayLists[cur].size(); i++) {
int next = arrayLists[cur].get(i);
if(!visited[next]) {
visited[next] = true;
System.out.print(next+" ");
linkedList.addLast(new int[]{next, i});
order = -1;
break;
}
}
// 没有找到能连接的点时。回退上一个点的order
if (i == arrayLists[cur].size()){
order = linkedList.removeLast()[1];
}
}
}
public static void main(String[] args) {
// 构建边
for (int i = 0; i < 11; i++) {
arrayLists[i] = new ArrayList<>();
}
arrayLists[1].add(2);
arrayLists[1].add(3);
arrayLists[2].add(4);
arrayLists[2].add(5);
arrayLists[3].add(6);
arrayLists[3].add(7);
arrayLists[4].add(8);
arrayLists[4].add(9);
arrayLists[5].add(10);
arrayLists[2].add(1);
arrayLists[3].add(1);
arrayLists[4].add(2);
arrayLists[5].add(2);
arrayLists[6].add(3);
arrayLists[7].add(3);
arrayLists[8].add(4);
arrayLists[9].add(4);
arrayLists[10].add(5);
dfs(1);
System.out.println();
dfs_stack(1);
}
}