- 对于深度优先遍历,使用递归实现是非常普遍的,但是递归算法往往比较难以理解,如果递归终止条件设置不好的话,容易出现死循环。我们来看看通过非递归方式如何实现深度优先遍历
算法
- 1、以图的邻接矩阵为例
- 2、使用一个stack来保存要访问的节点,每次都获取栈顶元素,然后遍历其对应的邻接点,如果遇到一个没有访问过的邻接点,则终止对其他邻接点的遍历,将该邻接点入栈,并进行下一轮循环,直到该元素的邻接点都被访问完了,然后该元素出栈
- 3、当栈为空时,就说明所有元素都被遍历了,循环终止
代码实现
该邻接矩阵对应的图如下:
public class DfsIterateAdjacentMatrix {
private static Map<Integer, String> idVertexMap = new HashMap<Integer, String>(){{
put(0,"V0");
put(1,"V1");
put(2,"V2");
put(3,"V3");
put(4,"V4");
put(5,"V5");
put(6,"V6");
put(7,"V7");
}};
private static int[][] adjacentMatrix = new int[][]{
//V0,V1,V2,V3,V4,V5,V6,V7
{0, 1, 1, 0, 0, 0, 0, 0},
{1, 0, 0, 1, 1, 0, 0, 0},
{1, 0, 0, 0, 0, 1, 1, 0},
{0, 1, 0, 0, 0, 0, 0, 1},
{0, 1, 0, 0, 0, 0, 0, 1},
{0, 0, 1, 0, 0, 0, 0, 0},
{0, 0, 1, 0, 0, 0, 0, 0},
{0, 0, 0, 1, 1, 0, 0, 0},
};
private static int[] visited = new int[adjacentMatrix.length];
public static void main(String[] args){
dfs();
}
private static void dfs(){
Stack<Integer> visitStack = new Stack<>();
visitStack.push(0);
visited[0]=1;
int lineNo = visitStack.peek();
System.out.println("visit: " + idVertexMap.get(lineNo));
while (!visitStack.isEmpty()){
lineNo = visitStack.peek();
int colNo = 0;
for (colNo =0; colNo < adjacentMatrix.length; colNo ++){
if (adjacentMatrix[lineNo][colNo] == 1 && visited[colNo] ==0){
visitStack.push(colNo);
visited[colNo] =1;
System.out.println("visit: " + idVertexMap.get(colNo));
break;
}
}
if (colNo == adjacentMatrix.length){
visitStack.pop();
}
}
}
}