Detailed Explanation of Breadth First Search Algorithm (BFS) (super detailed explanation, with large picture)

Table of contents

1. What is breadth-first search (BFS)?

2. Graphic wide search (BFS)

3. Comparison and discovery

Four. Tool - Queue

 5. Template

Six. Finally


1. What is breadth-first search (BFS)?

Baidu Encyclopedia says:

Breadth-first search algorithm (also known as breadth-first search) is one of the easiest graph search algorithms, and this algorithm is also the prototype of many important graph algorithms. Both Dijkstra's single-source shortest path algorithm and Prim's minimum spanning tree algorithm use ideas similar to breadth-first search. Its alias is also called BFS, which belongs to a blind search method, the purpose is to systematically expand and check all nodes in the graph to find the result. In other words, it exhaustively searches the entire graph until it finds a result, regardless of where the result might be.

Too theoretical, but said the core:

 It is a blind search method whose purpose is to systematically expand and examine all nodes in the graph to find a result. Regardless of the possible locations of the results, the entire graph is searched exhaustively until a result is found.

It was  also said:

It starts traversing from the position of the root node. After the traversal ends, it traverses the points adjacent to the root node in turn. After the adjacent point traversal ends, it continues to traverse the adjacent untraversed points of the first traversed node in the previous round until all Points are traversed to end.

generalKnowledge/Basic Algorithms/Breadth First Search.md jimmyflower6/Zhongshan No. 1 Middle School Information Competition- Gitee.com

 This is better said, but still a bit blunt.

In simple terms , it is:

Breadth-first search is an algorithm for searching a graph. Assuming that we are at a certain vertex (the starting point) at the beginning, we do not know the overall structure of the graph at this time, and our purpose is to search along the edge from the starting point until we reach the specified vertex (that is, the end point). In this process, every time a vertex is reached, it will be judged once whether it is the end point. Breadth-first search will first search from the vertex closest to the starting point.

Below, I will introduce this method to you in the form of a step-by-step diagram.


2. Graphic wide search (BFS)

 A is the start point and G is the end point. At the beginning we are at the starting point A, and we don't know where G is at this time.

The three vertices B, C, and D that can be directly reached from A are set as candidate vertices for the next step. 

Select a vertex from the candidate vertices. The vertex that becomes the candidate first is preferred . If multiple vertices become candidates at the same time, one of them can be selected at will. (Priority is given to the vertex that becomes the earliest candidate, which is a "first in, first out" method, which will be discussed later)

Here B, C, and D become candidates at the same time, so we randomly select the leftmost vertex B. 

Move to the selected vertex B. At this point we are on B, so B turns red, and turns the already searched vertices orange.

Here, candidate vertices are managed in a "first-in-first-out" (FIFO) manner, so the data structure "queue" can be used. (This structure will be explained later, please scroll down)

Two vertices E and F directly accessible from B are set as candidate vertices.

At this time, C and D are the earliest candidate vertices, and we choose the left vertex C. 

Move to the selected vertex C.

A vertex H directly accessible from C is set as a candidate vertex. 

Repeat the above operations until the end point is reached, or all vertices are traversed. 

The search order in this example is A, B, C, D, E, F, H, I, J, K. 

Finished searching from A to I, now at vertex J. 

When the end point G is reached, the search ends.

Supplementary note: From the above, we can know that the characteristic of breadth-first search is to start from the starting point and conduct extensive searches from near to far . Therefore, the closer the target vertex is to the starting point, the faster the search will end.


3. Comparison and discovery

The difference between DFS and BFS:
bfs traverses nodes first-in-first-out , and dfs traverses nodes first-in-last-out ;
bfs visits hierarchically , and dfs visits all the way to the end according to a path . When the current node has no unvisited neighbor nodes, it will go back to The last node, keep trying until the target node is visited or all nodes have been visited.
bfs is suitable for finding the shortest distance between the source point and the target node , for example: finding the shortest path. dfs is more suitable for solving one of any matching schemes or traversing all situations , such as: full arrangement, topological sorting, and finding any path to a certain point.

However, how to implement the first-in-first-out of breadth-first search (BFS)? Here, we use a data structure - queue. 


Four. Tool - Queue

Queue is a special kind of linear table , which is special in that it only allows delete operations at the front end of the table (front), and insert operations at the back end (rear) of the table. Like a stack, a queue is an operation subject to A linear list of constraints. The end of the insertion operation is called the tail of the queue, and the end of the deletion operation is called the head of the queue.

We can mark it with double pointers, mark the head and tail of the queue through the front pointer and the rear pointer, and then only allow addition, deletion, modification and query at the positions of the front and rear pointers, so that the restriction on the array is realized . This is a simulation of a queue using the data structure of an array. Beginners are advised to familiarize themselves with queues in this way first.

Specific operation:

/* 
    Usually the front is assigned a value of 0, and the rear is assigned a value of -1 
    to facilitate subsequent entry, exit, and retrieval of the first element 
 */ 
int a[100], front=0, rear=-1; 

// enter 
a[+ +rear] = 10; 

// dequeue 
front++ 

// get the first element 
a[front] 

// get the tail element 
a[rear] 

// judge whether it is empty 
if(front > rear) 
    cout << "the queue for empty team";

However, in the later stage, in order to save time, we can directly use the STL container that comes with C++ to complete the operation.

The specific operation is as follows:

// Import the queue package 
#include<queue> 

// Declare a queue object 
// Fill in the data type you want to fill 
queue<int> qu; 

// Enter the queue 
int a = 10; 
qu.push(a); 

// Queue out, no return value 
qu.pop(); 

// Get the first element 
int front = qu.front(); 

// Get the tail element 
int rear = qu.back(); 

// Whether the team is empty 
if( qu.empty()) { 
    cout << "The queue is empty"; 
} 

// Queue size, return int 
qu.size();

 5. Template

The topic of BFS has a set of obvious templates. If you don’t believe me, let’s take a look. (Core code will be shown)

Eight digit problem:


    while(!q.empty())//q非空,可以走
    {
        for(int i=0;i<4;i++)//四个方向
        {
            ma ac=q.front();
            int nx = ac.x0 + dx[i];
            int ny = ac.y0+ dy[i];
            if(nx>=1&&ny>=1&&nx<=3&&ny<=3)
            {
                swap(ac.a[ac.x0][ac.y0],ac.a[nx][ny]);
                ac.x0=nx;
                ac.y0=ny;
                //将0与目标数交换
                ac.ans++;//步数加1
                ac.kt=kt(ac);
                //康托判重
                 if (!flag[ac.kt])
                {
                    flag[ac.kt] = 1;
                    q.push(ac);
                    //加入队列
                    if(ac.kt==mo.kt)
                    { 
                        printf("%d",q.back().ans);
                        exit(0);
                    }
                }
            }
        }
        q.pop();
        //弹出已遍历完所有情况的矩阵
    }

Sea rescue mission:

		while(!q.empty())
		{
			for(int i=0;i<4;i++)
			{
				node ne;
				ne.x=q.front().x+dx[i],ne.y=q.front().y+dy[i];
				if(bo[ne.x][ne.y]==0&&ne.x>=0&&ne.y>=0&&ne.x<=n&&ne.y<=m&&a[ne.x][ne.y]==1)
				{
					ne.ans=q.front().ans+1;
					bo[ne.x][ne.y]=1;
					q.push(ne);
					if(ne.x==xe.x&&ne.y==xe.y)
					{
						flag=true;
						printf("%d\n",q.back().ans);
						break;
					}
				}
			}
			if(flag) break;
			q.pop(); 
		}

 Clever measure:

    while(scanf("%d%d%d%d",&t.a[1],&t.a[2],&t.a[3],&k)!=EOF)//多组数据
    {
        flag=false;
        memset(bo,0,sizeof(bo));
         
    	bo[t.a[1]][t.a[2]][t.a[3]]=1;
    	p.ans=0;
    	p.a[1]=t.a[1];
    	p.a[2]=p.a[3]=0;
    	q.push(p);
     	if(q.front().a[1]==k||q.front().a[2]==k||q.front().a[3]==k)
    	{
    	    printf("yes\n%d\n",0);
            continue;
    	}//特判 
    	while(!q.empty())
    	{
        	for(int i=1;i<=3;i++)
        	{
          		if(q.front().a[i]>0)
            	{
                	for(int j=1;j<=3;j++)
                	{
                    	node sy;
                    	sy=q.front();
                    	sy.ans ++;
                    	if(i!=j)
                    	{
                        	int T=t.a[j]-sy.a[j];
                        	if(sy.a[i]>T)
                        	{
                            	sy.a[j]=t.a[j];
                            	sy.a[i]=sy.a[i]-T;
                        	}
                        	else
                        	{
                            	sy.a[j]+=sy.a[i];
                            	sy.a[i]=0;
                        	}
                        	if(!bo[sy.a[1]][sy.a[2]][sy.a[3]])
                        	{
                            	bo[sy.a[1]][sy.a[2]][sy.a[3]]=1;
                            	if(sy.a[1]==k||sy.a[2]==k||sy.a[3]==k)
                            	{
                                	flag=true;
                            	}
                            	q.push(sy);
                        	}
                    	}
                	}
            	}
          
        	}//遍历每一种倒法 
        if(flag) break;
        q.pop();
    	}
    	if(flag)
    	{
        	printf("yes\n%d\n",q.back().ans);
    	}
    	else
    	{
        	printf("no\n");
    	}
    	while(!q.empty())
    	{
        	q.pop();
    	}
    }

I chose a few topics that were not so similar, but after a closer look, the structure is the same.

It can be expressed as a step diagram:

 In pseudocode, it is expressed like this:

int BFS(Node start, Node target) {
    入队(初始状态);
    visited[初始状态] = true;
    while(!空队) {
        for() { // 状态转换
            Node node = 队首元素;

            对node的处理,生成新node状态;

            if (visited[node] == true)
                continue;
            if (node == target) {
                输出答案;
                return 0;
            }
            v[node] = true;
            入队(node);
        }
    出队();
    }
    
}

This is the template for the BFS problem ! ! !

Six. Finally

Nothing, if you like it, give it a three-link ! Your support is my greatest motivation!

Guess you like

Origin blog.csdn.net/aliyonghang/article/details/128724989