赞
踩
目录
深度优先搜索(Depth-First Search,DFS)是一种常见的图遍历算法,用于在图或树等数据结构中探索所有可能的路径,以及查找特定目标(如寻找路径、判断连通性等)。DFS从一个起始顶点出发,沿着一条路径尽可能深入地访问顶点,直到不能继续为止,然后回溯到之前的顶点,继续尝试其他路径。这个过程通常使用递归来实现。
在图的DFS中,我们需要记录已经访问过的顶点,以避免无限循环。我们使用一个布尔数组来表示哪些顶点已经被访问过。从起始顶点开始,对于每个未访问的邻接顶点,我们递归地执行DFS。
下图为一个示例图,我们将对这个图进行DFS遍历
- //DFS算法
- bool visited[MAX_VERTICES]; //用于标记顶点是否被访问过,访问过为true
-
- void DFS(Graph G, int v) { //从顶点v出发,对图G进行深度优先遍历
- visit(G, v); //访问顶点v
- visited[v] = true; //标记已访问
- for (int w = getFirstNeighbor(G, v); w >= 0; w = getNextNeighbor(G, v,w)) {
- if (!visited[w]) { //w顶点没被访问
- DFS(G, w); //递归调用DFS
- }
- }
- }
- #include<iostream>
- using namespace std;
-
- //邻接矩阵定义图
- #define MAX_VERTICES 100 //顶点数目最大值
- typedef char VertexType; //顶点的数据类型
- typedef int EdgeType; //带权图中边上权值的数据类型
- struct Graph {
- int num_vertices, num_edge; // 图当前顶点和边的数量
- VertexType vex[MAX_VERTICES]; //顶点表
- EdgeType adj_matrix[MAX_VERTICES][MAX_VERTICES]; // 邻接矩阵,边表
- };
-
- //初始化
- void init_graph(Graph* graph, int num_vertices) {
- graph->num_vertices = num_vertices;
- graph->num_edge = 0;
- // 初始化邻接矩阵,初始值都为0(表示没有边)
- for (int i = 0; i < num_vertices; ++i) {
- //顶点数据赋值
- graph->vex[i] = 'a' + i;
-
- //邻接矩阵初始化
- for (int j = 0; j < num_vertices; ++j) {
- graph->adj_matrix[i][j] = 0;
- }
- }
- }
-
- //判断是否存在某条边(无向图)
- bool is_edge(Graph* graph, int source, int destination) {
- return graph->adj_matrix[source][destination] != 0 ||
- graph->adj_matrix[destination][source] != 0;
- }
-
- // 添加边,将邻接矩阵中对应的位置设为1(或边的权重值)
- void add_edge(Graph* graph, int source, int destination, int weight) {
- if (!is_edge(graph, source, destination)) {//不存在要添加的这条边
- graph->adj_matrix[source][destination] = weight;
- graph->adj_matrix[destination][source] = weight; // 对于无向图,需要设置对称位置
- graph->num_edge++;
- }
- else {
- cout << "此边已存在,不需要添加" << endl;
- }
-
- }
-
- //访问顶点
- void visit(Graph G, int v) { //访问顶点,这里是打印
- cout << G.vex[v];
- }
-
- // 求顶点v的第一个邻接点
- int getFirstNeighbor(Graph G, int v) {
- if (v >= 0 && v < G.num_vertices) {
- for (int i = 0; i < G.num_vertices; ++i) {
- if (G.adj_matrix[v][i] != 0) {
- return i;
- }
- }
- }
- return -1; // 顶点x没有邻接点或顶点索引无效
- }
-
- // 求顶点v的下一个邻接点
- int getNextNeighbor(Graph G, int v, int w) {
- if (v >= 0 && v < G.num_vertices) {
- for (int i = w + 1; i < G.num_vertices; ++i) {
- if (G.adj_matrix[v][i] != 0) {
- return i;
- }
- }
- }
- return -1; // 顶点x没有除y以外的下一个邻接点或顶点索引无效
- }
-
- //DFS算法
- bool visited[MAX_VERTICES]; //用于标记顶点是否被访问过,访问过为true
-
- void DFS(Graph G, int v) { //从顶点v出发,对图G进行深度优先遍历
- visit(G, v); //访问顶点v
- visited[v] = true; //标记已访问
- for (int w = getFirstNeighbor(G, v); w >= 0; w = getNextNeighbor(G, v, w)) {
- if (!visited[w]) { //w顶点没被访问
- DFS(G, w); //递归调用DFS
- }
- }
- }
-
- //DFSTraverse对图G进行广度优先遍历
- void DFSTraverse(Graph G) {
- for (int i = 0; i < G.num_vertices; i++) {
- visited[i] = false; //初始化标记数组
- }
- //无向图连通图任意一个顶点调用一次DFS即可访问到全部顶点
- DFS(G, 0); //从a开始
- //无向图若有多个连通分量,则每个连通分量都调用一次DFS
- //有向图调用一次DFS或者BFS不一定可以访问到所有顶点,得看它是不是强连通的
- }
-
- int main() {
- //创建一个图
- Graph G;
- Graph* graph = &G;
-
- //初始化
- init_graph(graph, 6);
-
- //添加边
- add_edge(graph, 0, 1, 1);//a-b
- add_edge(graph, 0, 2, 1);//a-c
- add_edge(graph, 0, 4, 1);//a-e
- add_edge(graph, 1, 4, 1);//e-b
- add_edge(graph, 4, 3, 1);//e-d
- add_edge(graph, 4, 5, 1);//e-f
- add_edge(graph, 3, 5, 1);//d-f
-
- //打印一下邻接矩阵
- cout << "所创建的图的邻接矩阵:" << endl;
- for (int i = 0; i < G.num_vertices; i++) {
- for (int j = 0; j < G.num_vertices; j++) {
- cout << G.adj_matrix[i][j];
- }
- cout << endl;
- }
- cout << endl;
-
- //DFS
- cout << "DFS遍历结果为:";
- DFSTraverse(G);
- return 0;
- }
完全没问题!!!!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。