Traversal of graphs - DFS, BFS

1. Traversal of the graph

Start from a vertex in the graph to visit the rest of the vertices in the graph, and each vertex is visited only once

There are two types of graph traversal: depth-first traversal DFS and breadth-first traversal BFS .

2. Depth-first traversal

Depth-first traversal is depth-first traversal, which is simply to go to the end every time. Preorder traversal similar to binary tree

Ideas:
1. Take a vertex as the starting point for depth-first traversal, and mark the vertex as visited
2. Select any path from the vertex as the starting point to traverse to the end, and mark the visited vertices
3. Step 2 After traversing to the end Go back to the previous vertex and repeat step
24. End of traversal of all vertices

According to the traversal idea, this is a recursive process. In fact, DFS is basically the same as backtracking.

Traverse:

insert image description here

Take this graph as an example for depth-first traversal

	static void dfs(int[][] graph,int idx,boolean[]visit) {
    
    
		int len = graph.length;
		//访问过
	 if(visit[idx]) return;
	 //访问该顶点
	 System.out.println("V"+idx);
	 //标志顶点
	 visit[idx] = true;
	 for(int i = 1;i < len;i++) {
    
    
	 //访问该顶点相连的所有边
		 if(graph[idx][i] == 1) {
    
    
	 //递归进行dfs遍历
		 dfs(graph, i, visit);
		 }
	 }
			
	}

Traversal results:
V1
V2
V3
V4
V5
V6
V7
V8
V9

The code to create the graph:

public static void main(String[] args) {
    
    
		Scanner scanner = new Scanner(System.in);
		//顶点数 以1开始
		int n = scanner.nextInt();
		int[][] graph = new int[n+1][n+1];
		//边数
		int m = scanner.nextInt();
		
		for(int i = 1;i <= m;i++) {
    
    
			int v1 = scanner.nextInt();
			int v2 = scanner.nextInt();
			graph[v1][v2] = 1;
			graph[v2][v1] = 1;
		}
		
		//标记数组 false表示未访问过 
		boolean[] visit = new boolean[n+1];
		dfs(graph, 1, visit);
		
	}

3. Use DFS to determine whether there is a cycle in a directed graph

Idea: When traversing a vertex, if there are other connected vertices that have been visited in addition to the previous vertex, there must be a cycle

	//默认无环
   static boolean flag = false;
	public static void main(String[] args) {
    
    
		Scanner scanner = new Scanner(System.in);
		//顶点数 以1开始
		int n = scanner.nextInt();
		int[][] graph = new int[n+1][n+1];
		//边数
		int m = scanner.nextInt();
		
		for(int i = 1;i <= m;i++) {
    
    
			int v1 = scanner.nextInt();
			int v2 = scanner.nextInt();
			graph[v1][v2] = 1;
			
		}
	 //标记数组 true为访问过
		boolean[] visit = new boolean[n+1];
		dfs(graph, 1, visit,1);
		if(flag) 
			System.out.println("有环");
		
	}
	
	static void dfs(int[][] graph,int idx,boolean[]visit,int parent) {
    
    
		int len = graph.length;
	
	 System.out.println("V"+idx);
	 //标记顶点
	 visit[idx] = true;
	 for(int i = 1;i < len;i++) {
    
    
		 //访问该顶点相连的所有边
		 if(graph[idx][i] == 1) {
    
    
		 if( !visit[i] ) {
    
    
		 dfs(graph, i, visit,idx);
		 }
		 else if(idx != i) {
    
    
			 flag = true;
		 }
		 }
	 }
	
	 
	}

Note: It is a directed graph to judge whether there is a cycle, and an undirected graph to judge whether there is a cycle is meaningless, because any two vertices with a path can be a cycle

4. Breadth-first traversal

Breadth-first traversal is breadth -first traversal. Order traversal similar to binary tree

Ideas:
1. Take a vertex as the starting point for breadth-first traversal, and mark the vertex as visited
2. Visit all vertices that are connected to the vertex and have not been visited, and mark the visited vertices
3. Visit with step 2 The obtained vertex is the starting point and repeat steps 1 and 2.
4. Traverse all vertices and end

The traversal is aided by the queue, and the queue dequeue order is the breadth-first traversal result
insert image description here

Traverse
insert image description here
this graph as an example, create a graph by adjacency matrix, and perform BFS traversal

	static void bfs(int[][] graph) {
    
    		
		int len = graph.length;
		//标记数组 false表示未访问过 
		boolean[] visit = new boolean[len];
		//辅助队列
		Queue<Integer> queue = new LinkedList<>();
		
		queue.offer(1);
		visit[1] = true;
		
		while(!queue.isEmpty()) {
    
    
			int num = queue.poll();
			System.out.println("V"+num);
					
			//遍历该顶点所有相连顶点
			for(int i = 1;i < len;i++) {
    
    
				//相连并且没有被访问过
				if(graph[num][i] == 1 && !visit[i]) {
    
    
					queue.offer(i);
					visit[i] = true;				
				}
			}
		}	
	}

Traversal result:
V1
V2
V6
V3
V7
V9
V5
V4
V8

The code to create the graph

public static void main(String[] args) {
    
    
		Scanner scanner = new Scanner(System.in);
		//顶点数 以1开始
		int n = scanner.nextInt();
		int[][] graph = new int[n+1][n+1];
		//边数
		int m = scanner.nextInt();
		
		for(int i = 1;i <= m;i++) {
    
    
			int v1 = scanner.nextInt();
			int v2 = scanner.nextInt();
			graph[v1][v2] = 1;
			graph[v2][v1] = 1;
		}
		bfs(graph);
	}

Guess you like

Origin blog.csdn.net/qq_52595134/article/details/123108852