图的遍历(graph traversal)

一、图的遍历
从图中某一顶点出发系统地访问图中所有顶点,使每个顶点恰好被访问一次,这种运算操作被称为图的遍历。为了避免重复访问顶点,需要记录已访问过的顶点。
图的遍历分为深度优先遍历和广度优先遍历

二、深度优先遍历(DFS)
从图中某结点出发,访问其相邻结点(按编号最小或最大),再访问该结点的相邻结点 ,直至访问完所有的结点。一条路走到头,回头再走没走过的路。可以看出DFS算法是一个递归的过程,其中需要借助一个栈完成操作。
基于邻接表的遍历的序列不唯一,基于邻接矩阵的遍历序列是唯一的。

深度优先遍历(从大到小):0,4,6,9,8,7,5,3,2,1。
深度优先遍历(从小到大):0,1,2,3,4,6,5,7,8,9。

图的深度遍历-邻接表1

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#include <iostream>

using namespace std;

const int MAX_VERTICES = 1000;

void DFSHelper(int** adjList, int numVertices, int vertex, bool* visited) {
    // mark the current vertex as visited
    visited[vertex] = true;
    // process the current vertex
    cout << vertex << " ";
    // recursively visit all adjacent vertices that have not been visited
    for (int i = 0; i < numVertices; ++i) {
        if (adjList[vertex][i] && !visited[i]) {
            DFSHelper(adjList, numVertices, i, visited);
        }
    }
}

void DFS(int** adjList, int numVertices, int startVertex) {
    // create an array to keep track of visited vertices
    bool visited[MAX_VERTICES] = {false};
    // call the recursive helper function on the starting vertex
    DFSHelper(adjList, numVertices, startVertex, visited);
}

int main() {
    // create an adjacency list for a graph with 4 vertices and 4 edges
    int numVertices = 4;
    int** adjList = new int*[numVertices];
    for (int i = 0; i < numVertices; ++i) {
        adjList[i] = new int[numVertices]();
    }
    adjList[0][1] = adjList[1][0] = 1;
    adjList[1][2] = adjList[2][1] = 1;
    adjList[2][3] = adjList[3][2] = 1;
    // perform a depth-first search starting at vertex 0
    DFS(adjList, numVertices, 0);
    // free memory
    for (int i = 0; i < numVertices; ++i) {
        delete[] adjList[i];
    }
    delete[] adjList;
    return 0;
}

图的深度遍历-邻接表2

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <iostream>
#include <vector>
#include <set>

using namespace std;

void DFSHelper(vector<vector<int>>& adjList, int vertex, set<int>& visited) {
    // mark the current vertex as visited
    visited.insert(vertex);
    // process the current vertex
    cout << vertex << " ";
    // recursively visit all adjacent vertices that have not been visited
    for (int neighbor : adjList[vertex]) {   //C++ 11 feature
        if (visited.find(neighbor) == visited.end()) {
            DFSHelper(adjList, neighbor, visited);
        }
    }
}

void DFS(vector<vector<int>>& adjList, int startVertex) {
    // create a set to keep track of visited vertices
    set<int> visited;
    // call the recursive helper function on the starting vertex
    DFSHelper(adjList, startVertex, visited);
}

int main() {
    // create an adjacency list for a graph with 4 vertices and 4 edges
    vector<vector<int>> adjList(4);
    adjList[0].push_back(1);
    adjList[1].push_back(0);
    adjList[1].push_back(2);
    adjList[2].push_back(1);
    adjList[2].push_back(3);
    adjList[3].push_back(2);
    // perform a depth-first search starting at vertex 0
    DFS(adjList, 0);
    return 0;
}

图的深度遍历-邻接矩阵

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include <iostream>
#include <cstring>

using namespace std;

const int MAX_VERTICES = 1000;

void DFSHelper(int** adjMatrix, int numVertices, int vertex, bool* visited) {
    // mark the current vertex as visited
    visited[vertex] = true;
    // process the current vertex
    cout << vertex << " ";
    // recursively visit all adjacent vertices that have not been visited
    for (int i = 0; i < numVertices; ++i) {
        if (adjMatrix[vertex][i] && !visited[i]) {
            DFSHelper(adjMatrix, numVertices, i, visited);
        }
    }
}

void DFS(int** adjMatrix, int numVertices, int startVertex) {
    // create an array to keep track of visited vertices
    bool visited[MAX_VERTICES];
    memset(visited, false, sizeof(visited));
    // call the recursive helper function on the starting vertex
    DFSHelper(adjMatrix, numVertices, startVertex, visited);
}

int main() {
    // create an adjacency matrix for a graph with 4 vertices and 4 edges
    int numVertices = 4;
    int** adjMatrix = new int*[numVertices];
    for (int i = 0; i < numVertices; ++i) {
        adjMatrix[i] = new int[numVertices];
        memset(adjMatrix[i], 0, numVertices * sizeof(int));
    }
    adjMatrix[0][1] = adjMatrix[1][0] = 1;
    adjMatrix[1][2] = adjMatrix[2][1] = 1;
    adjMatrix[2][3] = adjMatrix[3][2] = 1;
    // perform a depth-first search starting at vertex 0
    DFS(adjMatrix, numVertices, 0);
    // free memory
    for (int i = 0; i < numVertices; ++i) {
        delete[] adjMatrix[i];
    }
    delete[] adjMatrix;
    return 0;
}

三、广度优先遍历(BFS)

图的广度遍历-邻接表

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include <iostream>
#include <queue>
#include <vector>

using namespace std;

const int MAX_VERTICES = 1000;

void BFS(vector<int>* adjList, int numVertices, int startVertex) {
    // create an array to keep track of visited vertices
    bool visited[MAX_VERTICES] = { false };
    // create a queue to store the vertices to be processed
    queue<int> q;
    // mark the starting vertex as visited and add it to the queue
    visited[startVertex] = true;
    q.push(startVertex);
    // process the vertices in the queue
    while (!q.empty()) {
        // get the next vertex from the queue
        int vertex = q.front();
        q.pop();
        // process the current vertex
        cout << vertex << " ";
        // add all unvisited neighbors of the current vertex to the queue
        for (int i = 0; i < adjList[vertex].size(); ++i) {
            int neighbor = adjList[vertex][i];
            if (!visited[neighbor]) {
                visited[neighbor] = true;
                q.push(neighbor);
            }
        }
    }
}

int main() {
    // create an adjacency list for a graph with 4 vertices and 4 edges
    int numVertices = 4;
    vector<int> adjList[MAX_VERTICES];
    adjList[0].push_back(1);
    adjList[1].push_back(0);
    adjList[1].push_back(2);
    adjList[2].push_back(1);
    adjList[2].push_back(3);
    adjList[3].push_back(2);
    // perform a breadth-first search starting at vertex 0
    BFS(adjList, numVertices, 0);
    return 0;
}

图的广度遍历-邻接矩阵

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <iostream>
#include <queue>

using namespace std;

const int MAX_VERTICES = 1000;

void BFS(int adjMatrix[][MAX_VERTICES], int numVertices, int startVertex) {
    // create an array to keep track of visited vertices
    bool visited[MAX_VERTICES] = { false };
    // create a queue to store the vertices to be processed
    queue<int> q;
    // mark the starting vertex as visited and add it to the queue
    visited[startVertex] = true;
    q.push(startVertex);
    // process the vertices in the queue
    while (!q.empty()) {
        // get the next vertex from the queue
        int vertex = q.front();
        q.pop();
        // process the current vertex
        cout << vertex << " ";
        // add all unvisited neighbors of the current vertex to the queue
        for (int i = 0; i < numVertices; ++i) {
            if (adjMatrix[vertex][i] == 1 && !visited[i]) {
                visited[i] = true;
                q.push(i);
            }
        }
    }
}

int main() {
    // create an adjacency matrix for a graph with 4 vertices and 4 edges
    int numVertices = 4;
    int adjMatrix[MAX_VERTICES][MAX_VERTICES] = { { 0, 1, 0, 0 },
                                                  { 1, 0, 1, 0 },
                                                  { 0, 1, 0, 1 },
                                                  { 0, 0, 1, 0 } };
    // perform a breadth-first search starting at vertex 0
    BFS(adjMatrix, numVertices, 0);
    return 0;
}
Scroll to Top