图的深度优先遍历介绍
图遍历介绍
所谓图的遍历,即是对结点的访问。一个图有那么多个结点,如何遍历这些结点,需要特定策略,一般有两种访问策略:(1)深度优先遍历(2)广度优先遍历
深度优先遍历基本思想
1)深度优先遍历,从初始访问结点出发,初始访问结点可能有多个邻接结点,深度优先遍历的策略就是首先访问第一个邻接结点,然后再以这个被访问的邻接结点作为初始结点,访问它的第一个邻接结点,可以这样理解:每次都在访问完当前结点后首先访问当前结点的第一个邻接结点。
2)我们可以看到,这样的访问策略是优先往纵向挖掘深入,而不是对一个结点的所有邻接结点进行横向访问。
3)显然,深度优先搜索是一个递归的过程
代码如下:
//深度优先算法
private void dfs(boolean[] isVisited, int i ){
System.out.print(getValueByIndex(i) + "->");
//将节点设置为反问过
isVisited[i] = true;
int w = getFirstNeighbor(i);
while (w != -1){
if (!isVisited[w]){
dfs(isVisited, w);
}
w = getNextNeighbor(i, w);
}
}
//返回节点对应的数据
public String getValueByIndex(int i){
return vertexList.get(i);
}
//得到第一个邻接矩阵节点的下标
private int getFirstNeighbor(int index){
for (int i = 0; i < vertexList.size(); i++) {
if (edges[index][i] > 0){
return i;
}
}
return -1;
}
//根据前一个零阶矩阵节点的下标获取下一个邻接矩阵节点
public int getNextNeighbor(int v1, int v2){
for (int i = v2 + 1; i < vertexList.size(); i++) {
if (edges[v1][i] > 0){
return i;
}
}
return -1;
}
//对dfs 进行一个重载,遍历我们所有的节点,并进行dfs
public void dfs(){
for (int i = 0; i < getNumOfVertex(); i++) {
if (!isVisited[i]){
dfs(isVisited, i);
}
}
}
.图的广度优先遍历
类似于一个分层搜索的过程,广度优先遍历需要使用一个队列以保持访问过的结点的顺序,以便按这个顺序来访问这些结点的邻接结点。
代码如下:
private void bfs(boolean[] isVisited, int i){
int u; // 表示队列的头节点对应的下标
int w; // 领结节点w
//队列,记录节点访问顺序
LinkedList queue = new LinkedList();
//访问节点输出节点信息
System.out.print(getValueByIndex(i) + "=>");
isVisited[i] = true;
queue.addLast(i);
while (!queue.isEmpty()){
//取出队列头部
u = (int) queue.removeFirst();
//得到邻接点的下标W
w = getFirstNeighbor(u);
while (w != -1){
//是否访问过
if (!isVisited[w]){
System.out.print(getValueByIndex(w) + "=>");
isVisited[w] = true;
//入队
queue.addLast(w);
}
//以u为前驱点,找到w后面的下一个邻接点
w = getNextNeighbor(u , w);
}
}
}
//遍历所有节点都进行广度优先搜索
public void bfs(){
for (int i = 0; i < getNumOfVertex(); i++) {
if (!isVisited[i]){
bfs(isVisited, i);
}
}
}
ps:【源码自取,点击即可】
ps:以上笔记均来自尚硅谷韩顺平老师《Java数据结构与java算法》