Breadth-first search and depth-first search when adjacency linked list and matrix represent graphs

1. The basic representation of the graph:
G(V,E) represents the graph, V is the vector node, and E is the edge.
The adjacency list is often used to represent sparse graphs, and the adjacency matrix often represents dense graphs, Where the adjacency matrix is ​​often used when the graph scale is small, because the matrix is ​​simple.
Insert picture description here
The sum of the lengths of the adjacent linked lists of 2|E|undirected graphs is, and the sum of the lengths of adjacent linked lists of directed graphs is |E|.
Insert picture description here
2. Breadth-first search BFS:
BFS is the most basic algorithm for solving the shortest path without weight graph .
The single-source shortest path problem based on it is the shortest path solving problem of weighted graphs , and the solution is Dijkstra algorithm (based on BFS improvement).

After the algorithm finds all nodes whose distance from the source node s is k, it will find other nodes whose distance from the source node s is k+1.
Insert picture description here
Note: Breadth first search is aHierarchical searchIn the process, every step forward may visit a batch of vertices, unlike the depth-first search, there is no backtracking, so it is not a recursive algorithm. In order to achieve layer-by-layer access,The algorithm must use an auxiliary queue to record the next layer of vertices being visited
At the same time, the state of node access needs to be saved (to avoid repeated access), If it is in the form of adjacency matrix, use an array to save the node access state; if it is in the form of adjacency linked list, increase the node attributes in the linked list node.accessed = true.
2.1. Breadth-first search C++ code represented by adjacency matrix:
use array to save node access state

const int MaxNum = 10; // 图的大小10X10
int G[MaxNum ][MaxNum ]; // 表示图 ,顶点为数字0-9,此部分要随题变化
int visited[MaxNum ] = {
    
    0}; // 保存访问状态
int route[MaxNum ] ={
    
    -1}; //记录路径
queue<int> q; // 记录待访问节点
void BFS(int* G,int start) // 输入图与搜索起点,起点类型随题目而变
{
    
    
	visited[start] = 1;
	route[start] = -1; //源头,-1表示已经没有路了
	q.push(start);
	while(!q.empty()){
    
    
		int tmpnode = q.front();
		q.pop();
		for(int i = 0;i<MaxNum;i++){
    
    
			if(G[tmpnode][i] = 1 && visited[i] == 0){
    
     //1代表连接(有路) 
			//当两节点间连接且没访问过则进行处理:加入待放问列表
				route[i] = tmpnode; //路的来源
				q.push(i); 
				visited[i] = 1;
			}
		}
	}
}

//输出起点start到任一点的路径:
void route(int start, int end)
{
    
    
	vector<int> route_start_end;
	while( end !=-1){
    
    
		route_start_end.push_back(end);
		end = route[end];
	}
	for(int i = route_start_end.size()-1;i>=0;i--){
    
    
		std::cout<<route_start_end[i];
	}
}

2.2. The breadth-first search C++ code represented by the adjacency linked list:
you can also add the visited attribute to the node instead of the visited array

struct ListNode {
    
    
	int val;
	struct ListNode *next;
	ListNode(int x) : val(x), next(NULL) {
    
    }
}
const int MaxNum = 10; // 图的大小10X10
ListNode* G[MaxNum]; // 图,假设已经构造好了
void BFS(ListNode* G,int start) // 输入图与搜索起点,起点类型随题目而变
{
    
    
	int visited[MaxNum ] = {
    
    0}; // 保存访问状态
	int route[MaxNum ] ={
    
    -1}; //记录路径
	queue<ListNode*> q; // 记录待访问节点
	q.push(G[start]); //起点入队
	visited[start] = 1; //标识起点已经访问
	while(!q.empty()){
    
    
		ListNode* tmp = q.front();
		q.pop();
		while(tmp->next != null){
    
    
			if(visited[tmp->next->val]!=1){
    
    
				q.push(tmp->next);
				visited[tmp->next->val] = 1;
				route[tmp->next->val] =tmp->val; //记录路径
			}
			tmp = tmp->next;
		}
	}
}

2.3. Breadth-first search for non-unicom maps:

void BFSall(ListNode* G)
{
    
    
	for(int i = 0;i<MaxNum;i++){
    
    
		if(visited[i]!=1){
    
    
			BFS(G,i); // 若这个节点未访问过说明与其他节点不连通,从此节点开始再调用BFS 
		}
	}
}

Reference materials:
good: breadth first search (BFS) and depth first search (DFS) algorithm analysis of graphs
breadth first search (BFS) C++ implementation

3. Depth-first search:
Depth-first search is similar to the pre-order traversal of a tree,Need an array to record the visited nodes, and at the same time use recursion to return to the predecessor node when all nodes have been visited
3.1. Depth-first search C++ code represented by adjacency matrix:

int visited[MaxNum] = {
    
    0}; // 保存访问状态
void DFS(int* G,int start)
{
    
    
	visit(start); // 可以是输出、记录父节点等任何操作
	visited[start] = 1;
	for(int i = 0;i<MaxNum;i++){
    
    
		if(G[start][i]!=0 && visited[i]!=1){
    
    
			DFS(G,i);
		}
	}
} 

3.2. Depth-first search C++ code represented by adjacency linked list:

int visited[MaxNum] = {
    
    0}; // 保存访问状态
void DFS(ListNode* G,int start) //start为访问起点
{
    
    
	visit(start); // 可以是输出、记录前驱节点等任何操作
	visited[start] = 1;
	ListNode* head = G[start];
	while(head){
    
    
		ListNode* tmp = head->next;
		if(tmp && visited[tmp->val]!=1){
    
     //若节点存在且未访问,则递归进入
			DFS(G,tmp->val); 
		}
		head = tmp; //否则就退回源节点,转到链表其余节点
	}
} 

Reference material: analysis of breadth first search (BFS) and depth first search (DFS) algorithms of graphs

to sum up:

1. Breadth-first search is similar to sequence traversal. A queue is needed to store the nodes to be visited, and an attribute is needed to identify the access state of the node. To save the node path, a path array is also required.
2. Depth-first search is similar to pre-order traversal, implemented by recursion.
3. The starting point of BFS and DFS search is uncertain, so it is generally necessary to find the starting point first when solving problems.
4. Breadth first search algorithm can be usedFind the shortest path.

Guess you like

Origin blog.csdn.net/qq_33726635/article/details/105968253