数据结构与算法图遍历算法 ( 深度优先搜索代码示例 )
Posted 韩曙亮
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构与算法图遍历算法 ( 深度优先搜索代码示例 )相关的知识,希望对你有一定的参考价值。
文章目录
一、深度优先搜索算法
深度优先搜索算法步骤 : 将 深度优先搜索 算法步骤 转为代码 ;
- ① 访问初始结点 : 访问 初始结点 v , 并将该 初始结点 v 标记为 " 已访问 " ; 设置一个 访问标记 数组 , 数组元素个数与 顶点个数相同 ;
/**
* 判定顶点是否被访问
*/
private boolean[] isVisted;
- ② 查找邻接节点 : 查找 初始结点 v 的 第一个 邻接节点 w ;
/**
* 获取结点的第一个邻接结点
* @param index
* @return 如果存在 邻接结点 返回对应下标 , 如果不存在返回 -1
*/
public int getFirstNeighbor(int index)
for (int i = 0; i < vertexList.size(); i++)
if (edges[index][i] > 0)
return i;
return -1;
- ③ 邻接节点是否存在 :
- 如果 w 结点存在 , 执行 ④ 操作 判断该 结点 是否被访问 ;
- 如果 w 结点 不存在 , 回到 ① 查找 初始结点 v 的下一个 邻接节点 ;
/**
* 已知 v1 结点有一个邻接结点 v2, 找到 v2 之后的下一个 v1 的邻接结点
* @param v1
* @param v2
* @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;
- ④ 邻接节点是否被访问 :
- 如果 w 结点存在 并且 没有被访问 , 那么 对 w 结点 进行 深度优先遍历 , 将 w 结点 作为 新的 初始结点 v , 从 ① 步骤开始执行 ;
- 如果 w 结点存在 但是 被访问了 , 那么 查找 w 结点的 下一个 邻接节点 , 转到步骤 ③ 执行 ;
/**
* 递归核心函数, 给定一个初始结点, 找到其第一个邻接结点, 如果该邻接结点没有被访问,
* 将新结点作为 初始结点 , 进行递归遍历
* @param isVisted
* @param i
*/
public void dfs(boolean[] isVisted, int i)
// 访问初始结点
System.out.println("Visit Vertex : " + getVertexByIndex(i));
// 设置 i 结点已访问
isVisted[i] = true;
// 查找 i 结点的第一个邻接结点 w
int w = getFirstNeighbor(i);
// 如果不存在 第一个邻接结点 则返回 -1
// 如果存在 , 返回 该结点 索引
while (w != -1)
// 确保找到的 第一个 邻接结点 没有访问过
if (!isVisted[w])
// 以 w 为初始结点 , 进行递归
dfs(isVisted, w);
// 如果 第一个 邻接结点 已访问
// 那么找到 i 作为初始结点 , w 作为 第一个邻接结点 , 之后的 第二个邻接结点
w = getNextNeighbor(i, w);
遍历的入口函数 : 一般情况下只需要一个结点 , 就可以将所有的结点遍历完毕 ;
/**
* 遍历入口函数
*/
public void dfs()
for (int i = 0; i < getNumberOfVertex(); i++)
if (!isVisted[i])
dfs(isVisted, i);
二、完整代码示例
完整代码示例
import java.util.ArrayList;
import java.util.Arrays;
public class Graph
/**
* 图顶点
*/
private ArrayList<String> vertexList;
/**
* 图的邻接矩阵
*/
private int[][] edges;
/**
* 图中边的数据
*/
private int numOfEdges;
/**
* 判定顶点是否被访问
*/
private boolean[] isVisted;
/**
* 构造器
* @param n 顶点个数
*/
public Graph(int n)
// 创建 n x n 邻接矩阵
edges = new int[n][n];
// 初始化顶点容器
vertexList = new ArrayList<>(n);
// 边数量统计
numOfEdges = 0;
// 顶点是否被访问标志位
isVisted = new boolean[n];
/**
* 插入顶点
* @param vertex 顶点名称
*/
public void insertVertex(String vertex)
vertexList.add(vertex);
/**
* 插入边
* @param v1 起始顶点索引
* @param v2 终止顶点索引
* @param weight 顶点的权重
*/
public void insertEdge(int v1, int v2, int weight)
edges[v1][v2] = weight;
edges[v2][v1] = weight;
// 边的数量增加 1
numOfEdges++;
/**
* 获取结点个数
* @return
*/
public int getNumberOfVertex()
return vertexList.size();
/**
* 获取边的个数
* @return
*/
public int getNumberOfEdges()
return numOfEdges;
/**
* 获取指定节点的索引值
* @param i
* @return
*/
public String getVertexByIndex(int i)
return vertexList.get(i);
/**
* 获取 v1 到 v2 的权值
* @param v1
* @param v2
* @return
*/
public int getWeight(int v1, int v2)
return edges[v1][v2];
/**
* 打印邻接矩阵
*/
public void showGraph()
for (int i = 0; i < edges.length; i++)
System.out.println(Arrays.toString(edges[i]));
/**
* 获取结点的第一个邻接结点
* @param index
* @return 如果存在 邻接结点 返回对应下标 , 如果不存在返回 -1
*/
public int getFirstNeighbor(int index)
for (int i = 0; i < vertexList.size(); i++)
if (edges[index][i] > 0)
return i;
return -1;
/**
* 已知 v1 结点有一个邻接结点 v2, 找到 v2 之后的下一个 v1 的邻接结点
* @param v1
* @param v2
* @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;
/**
* 递归核心函数, 给定一个初始结点, 找到其第一个邻接结点, 如果该邻接结点没有被访问,
* 将新结点作为 初始结点 , 进行递归遍历
* @param isVisted
* @param i
*/
public void dfs(boolean[] isVisted, int i)
// 访问初始结点
System.out.println("Visit Vertex : " + getVertexByIndex(i));
// 设置 i 结点已访问
isVisted[i] = true;
// 查找 i 结点的第一个邻接结点 w
int w = getFirstNeighbor(i);
// 如果不存在 第一个邻接结点 则返回 -1
// 如果存在 , 返回 该结点 索引
while (w != -1)
// 确保找到的 第一个 邻接结点 没有访问过
if (!isVisted[w])
// 以 w 为初始结点 , 进行递归
dfs(isVisted, w);
// 如果 第一个 邻接结点 已访问
// 那么找到 i 作为初始结点 , w 作为 第一个邻接结点 , 之后的 第二个邻接结点
w = getNextNeighbor(i, w);
/**
* 遍历入口函数
*/
public void dfs()
for (int i = 0; i < getNumberOfVertex(); i++)
if (!isVisted[i])
dfs(isVisted, i);
public static void main(String[] args)
// 创建图
Graph graph = new Graph(5);
// 添加顶点
graph.insertVertex("A");
graph.insertVertex("B");
graph.insertVertex("C");
graph.insertVertex("D");
graph.insertVertex("E");
// 添加边
graph.insertEdge(0, 1, 1); // AB
graph.insertEdge(0, 2, 1); // AC
graph.insertEdge(1, 0, 1); // BA
graph.insertEdge(1, 2, 1); // BC
graph.insertEdge(1, 3, 1); // BD
graph.insertEdge(1, 4, 1); // BE
graph.insertEdge(2, 1, 1); // CA
graph.insertEdge(2, 2, 1); // CB
graph.insertEdge(3, 1, 1); // DB
graph.insertEdge(4, 1, 1); // EB
// 打印临街矩阵
graph.showGraph();
// 深度优先搜索遍历
graph.dfs();
执行结果
> Task :Graph.main()
[0, 1, 1, 0, 0]
[1, 0, 1, 1, 1]
[1, 1, 1, 0, 0]
[0, 1, 0, 0, 0]
[0, 1, 0, 0, 0]
Visit Vertex : A
Visit Vertex : B
Visit Vertex : C
Visit Vertex : D
Visit Vertex : E
以上是关于数据结构与算法图遍历算法 ( 深度优先搜索代码示例 )的主要内容,如果未能解决你的问题,请参考以下文章