参考:http://blog.csdn.net/lalor/article/details/6845788
深度优先遍历的非递归实现:
思路:首先想到的是使用栈来实现,访问给定结点后,进栈;找到该结点的一个未访问的邻接点,访问、进栈;再对栈顶元素进行同样操作,找到它的一个未访问的邻接点,访问、进栈;依次类推,直到栈空。
伪代码:
1.栈的初始化;
2.输出起始顶点;起始顶点置为已访问,将起始顶点压入栈;
3.重复下列操作,直到栈空:
3.1 取栈顶元素顶点,注意这里不出栈;
3.2 如果栈顶元素顶点存在未被访问过的邻接点w,则
3.2.1 输出顶点w;
3.2.2 将顶点w置为已访问;
3.2.3 将顶点w进栈;
否则,当前顶点出栈。
下面是采用邻接表实现的遍历算法:
public abstract class AbstractGraph<V> {
protected List<V> vertices;//存储顶点的名字列表
protected List<List<Integer>> neighbors;//使用邻接表表示图,neighbors是一个数组,每一项是一个Integer类型的List,保存每一个顶点的相邻结点。
public AbstractGraph(int[][] edges,List<V> vertices) {
this.vertices = vertices;
createAdjacenyLists(edges, vertices.size());
}
private void createAdjacenyLists(int[][] edges, int numberOfVertices) {
neighbors = new ArrayList<List<Integer>>();
for(int i = 0; i < numberOfVertices; i++) {
neighbors.add(new ArrayList<Integer>());
}
System.out.println("edges.length = " + edges.length);
for(int i = 0; i < edges.length;i++) {
int startIndex = edges[i][0];
int endIndex = edges[i][1];
neighbors.get(startIndex).add(endIndex);
}
}
public void dfsRecurision(int v) {
List<Integer> searchOrders = new ArrayList<Integer>(); //searchOrders保存搜索的结点顺序
int[] parent = new int[vertices.size()];
for(int i = 0; i < parent.length;i++) {
parent[i] = -1;
}
boolean[] isVisited = new boolean[vertices.size()];
dfs(v,parent,searchOrders,isVisited);
}
private void dfs(int v, int[] parents,List<Integer> searchOrders, boolean[] isVisited){
searchOrders.add(v);
System.out.println("DFS: " + v);
isVisited[v] = true;
for(int i : neighbors.get(v)) {
if(!isVisited[i]) {
parents[i] = v;
dfs(i,parents,searchOrders,isVisited);
}
}
}
public void dfsNoRecursion(int v) {
List<Integer> searchOrders = new ArrayList<Integer>();
boolean[] isVisited = new boolean[vertices.size()];
Stack<Integer> searchStack = new Stack<Integer>();
searchOrders.add(v);
isVisited[v] = true;
searchStack.push(v);
boolean hasUnvisitedNeighbor;
while (!searchStack.isEmpty()) {
int topElement = searchStack.peek();
hasUnvisitedNeighbor = false;
for (int i : neighbors.get(topElement)) {
if (!isVisited[i]) {
searchOrders.add(i);
isVisited[i] = true;
searchStack.push(i);
hasUnvisitedNeighbor = true;
break;
}
}
if(!hasUnvisitedNeighbor) {
searchStack.pop();
}
}
}
public void bfsNoRecurison(int v) {
List<Integer> searchOrder = new ArrayList<Integer>();
LinkedList<Integer> queue = new LinkedList<Integer>();
boolean[] isVisited = new boolean[vertices.size()];
queue.offer(v);
isVisited[v] = true;
while(!queue.isEmpty()) {
int u = queue.poll();
System.out.println("BFS: " + u);
searchOrder.add(u);
for(int w : neighbors.get(u)) {
if(!isVisited[w]) {
queue.offer(w);
isVisited[w] = true;
}
}
}
}
}