无向图的深度优先与广度优先搜索代码实现

图采用了邻接表的形式储存。

带不带权都无所谓的

深度优先搜索 Depth First Search

道理和树的先序遍历差不多,把将要访问的点入栈,然后从栈里取点进行访问。

有些被调用的函数的具体代码将会在文章最后补上 ,但是函数功能看注释就好了

 1 void GraphAdjacencyListWeight::DFSAdvanced(int StartVertex) {
 2     int *visited = new int[VertexNumber];
 3     memset(visited, 0, VertexNumber * sizeof(int));
 4 
 5     stack<int> S;
 6     S.push(StartVertex);
 7 
 8     int NextVertex = -1;
 9 
10     while (!IsAllVisited(visited)) {
11         //如果有其他的连通分量
12         if (S.empty()) {
13             //随便找一个没被访问的点丢进栈
14             for (int lop = 0; lop < VertexNumber; lop++) {
15                 if (visited[lop] == 0) {
16                     S.push(lop);
17                     break;
18                 }
19             }
20         }
21         while (!S.empty()) {
22             NextVertex = S.top();
23             S.pop();
24 
25             if (visited[NextVertex] != 1) {
26                 //访问该点
27                 VisitVertex(NextVertex);
28                 //标记为访问过
29                 visited[NextVertex] = 1;
30                 //将下一个没被访问过的邻接点入栈
31                 PushValidVertexToStack(S, NextVertex, visited);
32             }
33         }
34     }
35     delete []visited;
36 }
DFS

令人惊讶的是广度优先搜索与深度优先搜索的代码居然是几乎相同的,除了栈换成队列。。。惊呆

广度优先搜索 Breadth First Search

广度优先搜索的过程和树的层序遍历类似 

 1 //广度优先
 2 void GraphAdjacencyListWeight::BFSAdvanced(int StartVertex) {
 3     int *visited = new int[VertexNumber];
 4     memset(visited, 0, VertexNumber * sizeof(int));
 5 
 6     queue<int> Q;
 7     Q.push(StartVertex);
 8 
 9     //下一个将要访问的顶点的序号
10     int NextVertex = -1;
11 
12     //当还有顶点没被访问时
13     while (!IsAllVisited(visited)) {
14         //如果有其他的连通分量
15         if (Q.empty()) {
16             //随便找一个没被访问的点丢进队列
17             for (int lop = 0; lop < VertexNumber; lop++) {
18                 if (visited[lop] == 0) {
19                     Q.push(lop);
20                     break;
21                 }
22             }
23         }
24 
25         while (!Q.empty()) {
26             //获取队列前端元素
27             NextVertex = Q.front();
28             Q.pop();
29 
30             //如果该点没被访问过
31             if (visited[NextVertex] != 1) {
32                 //访问该点
33                 VisitVertex(NextVertex);
34                 //标记为访问过
35                 visited[NextVertex] = 1;
36                 //将该点的邻接点入队
37                 EnQueueAllAdjVer(Q, NextVertex);
38             }
39         }
40     }
41     delete []visited;
42 }
BFS

下面贴上完整的用到的函数的代码

 1 int GraphAdjacencyListWeight::IsAllVisited(int visit[]) {
 2     for (int lop = 0; lop < VertexNumber; lop++) {
 3         if (visit[lop] == 0) {
 4             return 0;
 5         }
 6     }
 7     return 1;
 8 }
 9 
10 void GraphAdjacencyListWeight::VisitVertex(int i) {
11     cout << "Vertex : " << VectorVertexList[i]->VertexIndex << endl;
12 }
13 
14 void GraphAdjacencyListWeight::EnQueueAllAdjVer(queue<int> &Q, int index) {
15     for (auto tmpPtr = VectorVertexList[index]->firstArc; tmpPtr != nullptr; tmpPtr = tmpPtr->nextArc) {
16         Q.push(tmpPtr->AdjacencyNode);
17     }
18 }
19 
20 void GraphAdjacencyListWeight::PushValidVertexToStack(stack<int> &S, int index, int visit[]) {
21     for (auto Ptr = VectorVertexList[index]->firstArc; Ptr != nullptr; Ptr = Ptr->nextArc) {
22         if (visit[Ptr->AdjacencyNode] != 1) {
23             S.push(Ptr->AdjacencyNode);
24             return;
25         }
26     }
27 }
Functions

 最后一行的 return; 不要

 全部代码请看 GitHub

原文地址:https://www.cnblogs.com/makejeffer/p/5031272.html