Data structure - Depth-first traversal of the graph (DFS)

——The content of this section is the content notes of P60 video of Bilibili Wangdao Postgraduate Entrance Examination "Data Structure".


Table of contents

1. Connection with depth-first traversal of trees

2. Implementation of DFS algorithm

1.Illustration

 2. Code implementation

3. Code explanation

3. Complexity Analysis

1. Space complexity

2. Time complexity

4. Depth-first spanning tree

1.Illustration

2. Uniqueness

3. Depth-first forest generation

5. Graph traversal and graph connectivity

1. Undirected graph

2. Directed graph


1. Connection with depth-first traversal of trees

1. Depth-first traversal of a graph is similar to depth-first traversal of a tree, that is, root-first traversal (recursive implementation);

2. Code:

void PreOrder(TreeNode *R)
{
    if(R!=NULL)
    {
        visit(R);                //访问根结点
        while(R还有下一个子树T)
            PreOrder(T);         //先根遍历下一棵子树
    }
}

2. Implementation of DFS algorithm

1.Illustration

 2. Code implementation

bool visited[MaxVertexNum];					//访问标记数组

void DFSTraverse(MGraph G)					//对图G进行深度优先遍历
{
	for (int v = 0; v < G.vexnum; ++v)
		visited[v] = false;					//初始化已访问标记数据
	for (int v = 1; v < G.vexnum; ++v)		
		if (!visited[v])
			DFS(G, v);
}

void DFS(MGraph G, int v)					//从顶点v出发,深度优先遍历图G
{
	visit(v);								//访问顶点v
	visited[v] = true;						//设已访问标记
	for(int w=FirstNeighbor(G,v);w>=0;w=NextNeighbor(G,v,w))
		if (!visited[w])					//w为u的尚未访问的邻接顶点
		{
			DFS(G, w);
		}
}

3. Code explanation

(1) The DFSTraverse(Graph G) function is used when all nodes of a non-connected graph cannot be traversed. The idea is the same as BFSTraverse in breadth-first traversal;

(2) The DFS function is implemented recursively. Each time the DFS function is called, one adjacent point of a node will be traversed and then another adjacent point will be traversed;


3. Complexity Analysis

1. Space complexity

(1) From the function call stack;

(2) In the worst case, the recursion depth is O(|V|);

 (3) Best case: O(1);

 

2. Time complexity

(1) Time complexity = time required to access each node + time required to explore each edge

(2) Adjacency matrix:

        ​​​​ ①Accessing |V| vertices requires O(|V|) time;

        ​​​​ ②It takes O(|V|) time to find the adjacent points of each vertex, and there are a total of |V| vertices;

        ③Time complexity=O(|V|^{2});

(3) Adjacency list:

        ​​​​ ①Accessing |V| vertices requires O(|V|) time;

        ​ ​ ②It takes a total of O(|E|) time to find the adjacent points of each vertex;

        ③ Time complexity = O(|V|+|E|);


4. Depth-first spanning tree

1.Illustration

2. Uniqueness

        ​​​​ ①The adjacency matrix representation of the same graph is not unique, so the depth-first traversal sequence is unique, and the depth-first spanning tree is also unique;

        ​​​​ ②The adjacency list of the same graph is not unique, so the depth-first traversal sequence is not unique, and the depth-first spanning tree is not unique either;

3. Depth-first forest generation

 

 


5. Graph traversal and graph connectivity

1. Undirected graph

        ​ ​ ① Perform BFS/DFS traversal on the undirected graph, the number of calls to the BFS/DFS function = the number of connected components;

        ​​​​②For connected graphs, BFS/DFS only needs to be called once;

2. Directed graph

        ​ ​ ① Perform BFS/DFS traversal on the directed graph, and the number of calls to the BFS/DFS function should be analyzed in detail;

        ​ ​ ②If there are paths from the starting vertex to every other vertex, the BFS/DFS function only needs to be called once;

        ​ ​ ③For strongly connected graphs, BFS/DFS only needs to be called once from any node.

Guess you like

Origin blog.csdn.net/weixin_64084604/article/details/128375709