深度优先遍历DFS用邻接表表示的图
遍历 深度 表示 DFS 优先 邻接
2023-09-27 14:28:46 时间
深度优先遍历用邻接表表示的图 DFS the Adjacency List Graph
图的BFS/DFS 树是一种特殊的图:有向无环图 图分为有向图和无向图 无向图可以看作是特殊的有向图,一条边a-b可以建立一条a到b的,再建立一条b到a的
C++实现图 - 02 图的遍历(DFS、BFS) 上一讲我们对图有了一个大概的了解,但是只讲了如何存储图,还没有讲如何遍历图。这一讲我们来介绍图的遍历方式,一共分为深度优先搜索(DFS)和宽度优先搜索(BFS)。
图的广度优先搜索和深度优先搜索(邻接链表表示) 邻接表表示法将图以邻接表(adjacency lists)的形式存储在计算机中。所谓图的邻接表,也就是图的所有节点的邻接表的集合;而对每个节点,它的邻接表就是它的所有出弧。邻接表表示法就是对图的每个节点,用一个单向链表列出从该节点出发的所有弧,链表中每个单元对应于一条出弧。为了记录弧上的权,链表中每个单元除列出弧的另一个端点外,还可以包含弧上的权等作为数据域。图的整个邻接表可以用一个指针数组表示。例如下图所示,邻接表表示为
一、简介
创建了图之后,我们希望从图中某个顶点出发访遍图中其余顶点,且使每个顶点仅被访问一次。这一过程就是图的遍历(Traversing Graph)。图的遍历算法是求解图的连通性问题、拓朴排序和求解关键路径等算法的基础。
深度优先搜索(Depth First Search)是一种递归的遍历方法。其过程为从图中任意一顶点出发,访问与其相连接的未被访问的顶点。因此,遍历图的过程实质上是对每个顶点查找其邻接点的过程。
二、实现代码
依然使用邻接表来表示图的存储结构,深度优先遍历程序如下代码所示:
1: //------------------------------------------------------------------------------
2: // Copyright (c) 2012 eryar All Rights Reserved.
3: //
4: // File : Main.cpp
5: // Author : eryar@163.com
6: // Date : 2012-8-25 17:11
7: // Version : 0.1v
8: //
9: // Description : Use Adjacency List data structure to store Digraph.
10: //
11: //==============================================================================
12:
13: #include vector
14: #include string
15: #include iostream
16: using namespace std;
17:
18: struct SVertexNode
19: {
20: bool bIsVisited;
21: string data;
22: vector int vecLoc;
23: };
24:
25: typedef struct SEdge
26: {
27: int iInitialNode;
28:
29: int iTerminalNode;
30:
31: }Edge;
32:
33: typedef struct SGraph
34: {
35: int iVertexNum;
36: int iEdgeNum;
37: vector SVertexNode vecVertex;
38: }Graph;
39:
40: ///////////////////////////////////////////////////////////////////////////////
41: // Functions of Graph
42: void Initialize(Graph g, int v);
43: Edge MakeEdge(int v, int w);
44: void InsertEdge(Graph g, const Edge e);
45: void ShowGraph(const Graph g);
46:
47: // Use Depth First Search method to Traverse the graph.
48: void DepthFirstSearch(Graph g);
49: void DepthFirstSearch(Graph g, int v);
50:
51: ///////////////////////////////////////////////////////////////////////////////
52: // Main function.
53:
54: int main(int agrc, char* argv[])
55: {
56: Graph aGraph;
57:
58: // Initialize the graph.
59: Initialize(aGraph, 4);
60:
61: // Insert some edges to make graph.
62: InsertEdge(aGraph, MakeEdge(0, 1));
63: InsertEdge(aGraph, MakeEdge(0, 2));
64: InsertEdge(aGraph, MakeEdge(2, 3));
65: InsertEdge(aGraph, MakeEdge(3, 0));
66:
67: // Show the graph.
68: ShowGraph(aGraph);
69:
70: // DFS traverse the graph.
71: DepthFirstSearch(aGraph);
72:
73: return 0;
74: }
75:
76: ///////////////////////////////////////////////////////////////////////////////
77:
78: /**
79: * brief Initialize the graph.
80: *
81: * v: vertex number of the graph.
82: */
83: void Initialize( Graph g, int v )
84: {
85: char szData[6];
86: SVertexNode node;
87:
88: g.iVertexNum = v;
89: g.iEdgeNum = 0;
90:
91: for (int i = 0; i i++)
92: {
93: sprintf(szData, "V%d", i+1);
94: node.data = szData;
95: node.bIsVisited = false;
96: g.vecVertex.push_back(node);
97: }
98: }
99:
100: /**
101: * brief Make an edge by initial node and terminal node.
102: */
103: Edge MakeEdge( int v, int w )
104: {
105: Edge e;
106:
107: e.iInitialNode = v;
108: e.iTerminalNode = w;
109:
110: return e;
111: }
112:
113: /**
114: * brief Insert an edge to the graph.
115: */
116: void InsertEdge( Graph g, const Edge e )
117: {
118: g.vecVertex.at(e.iInitialNode).vecLoc.push_back(e.iTerminalNode);
119:
120: // If the graph is Undigraph, need do something here...
121: //g.vecVertex.at(e.iTerminalNode).vecLoc.push_back(e.iInitialNode);
122:
123: g.iEdgeNum++;
124: }
125:
126: /**
127: * brief Show the graph.
128: */
129: void ShowGraph( const Graph g )
130: {
131: cout "Show the graph: " endl;
132:
133: for (int i = 0; i g.iVertexNum; i++)
134: {
135: cout "Node " i "(" g.vecVertex.at(i).data ")";
136:
137: for (int j = 0; j g.vecVertex.at(i).vecLoc.size(); j++)
138: {
139: cout "- " g.vecVertex.at(i).vecLoc.at(j);
140: }
141:
142: cout endl;
143: }
144: }
145:
146: void DepthFirstSearch( Graph g )
147: {
148: cout "Depth First Search the graph:" endl;
149:
150: for (int i = 0; i g.iVertexNum; i++)
151: {
152: if (!(g.vecVertex.at(i).bIsVisited))
153: {
154: DepthFirstSearch(g, i);
155: }
156: }
157: }
158:
159: void DepthFirstSearch(Graph g, int v)
160: {
161: int iAdjacent = 0;
162: SVertexNode node = g.vecVertex.at(v);
163:
164: // Visit the vertex and mark it.
165: cout g.vecVertex.at(v).data endl;
166: g.vecVertex.at(v).bIsVisited = true;
167:
168: // Visit the adjacent vertex.
169: for (int i = 0; i node.vecLoc.size(); i++)
170: {
171: iAdjacent = node.vecLoc.at(i);
172:
173: if (!(g.vecVertex.at(iAdjacent).bIsVisited))
174: {
175: DepthFirstSearch(g, iAdjacent);
176: }
177: }
178:
179: }
180:
181:
三、输出结果
1: Show the graph:
2: Node 0(V1)- 1- 2
3: Node 1(V2)
4: Node 2(V3)- 3
5: Node 3(V4)- 0
6: Depth First Search the graph:
7: V1
8: V2
9: V3
10: V4
图的BFS/DFS 树是一种特殊的图:有向无环图 图分为有向图和无向图 无向图可以看作是特殊的有向图,一条边a-b可以建立一条a到b的,再建立一条b到a的
C++实现图 - 02 图的遍历(DFS、BFS) 上一讲我们对图有了一个大概的了解,但是只讲了如何存储图,还没有讲如何遍历图。这一讲我们来介绍图的遍历方式,一共分为深度优先搜索(DFS)和宽度优先搜索(BFS)。
图的广度优先搜索和深度优先搜索(邻接链表表示) 邻接表表示法将图以邻接表(adjacency lists)的形式存储在计算机中。所谓图的邻接表,也就是图的所有节点的邻接表的集合;而对每个节点,它的邻接表就是它的所有出弧。邻接表表示法就是对图的每个节点,用一个单向链表列出从该节点出发的所有弧,链表中每个单元对应于一条出弧。为了记录弧上的权,链表中每个单元除列出弧的另一个端点外,还可以包含弧上的权等作为数据域。图的整个邻接表可以用一个指针数组表示。例如下图所示,邻接表表示为
相关文章
- 笔记:结构体类型和链表的建立、遍历、插入、删除
- 【LeetCode】分割回文串 [M](深度优先遍历)
- 【LeetCode】解数独 [H](深度优先遍历)
- python dictionary的遍历
- Java 8 及其后续版本的新遍历 forEach
- 64位内开发第二十四讲,内核中模块的遍历-3种方式
- C#实现图的深度优先遍历递归算法--详细代码
- 利用dfs深度遍历
- Jquery遍历之获取子级元素、同级元素和父级元素
- 大数据学习[16]--使用scroll实现Elasticsearch数据遍历和深度分页[转]
- TypeScript 数组遍历方法:map
- LeetCode_二叉树_BFS_中等_107.二叉树的层序遍历 II
- 24个 JavaScript 循环遍历方法,你都知道吗
- 遍历PspCidTable表检测隐藏进程
- 搜索引擎的那些事(多线程web遍历)
- 【数据结构与算法】图遍历算法 ( 深度优先搜索 DFS | 深度优先搜索和广度优先搜索 | 深度优先搜索基本思想 | 深度优先搜索算法步骤 | 深度优先搜索理论示例 )
- 8种遍历方法执行速度深度
- [LeetCode] 103. Binary Tree Zigzag Level Order Traversal 二叉树的之字形层序遍历
- python、java实现二叉树,细说二叉树添加节点、深度优先(先序、中序、后续)遍历 、广度优先 遍历算法
- 图的深度遍历和广度遍历