广度优先搜索算法C++(笔记)

实现思路

  • 第1步:考虑要导航的图形。

  • 第2步:选择图中的任何顶点(列如v1),你要从中遍历该图。

  • 第3步:利用以下两种数据结构来遍历图。

    • 访问数组(图形的大小)
    • 队列数据结构
  • 第4步:将起始顶点添加到已访问数组中,然后将v1的相邻顶点添加到队列数据结构中。

  • 第5步:现在使用先进先出的概念,从队列中移除第一个元素,将其放入已访问数组中,然后将被移除元素的相邻顶点添加到队列中。

  • 第6步:重复第5步,直到队列不为空,没有顶点可以访问。

列子:

Graph上的BFS遍历的实现:

// 此处,Graph 是我们已有的图,X 是源节点
Breadth_First_Search( Graph, X ):
    让 Q 为队列
    Q.enqueue( X ) // 将源节点 X 插入队列 将
    X 节点标记为已访问.

    while ( Q is not empty )
        Y = Q.dequeue( ) // 从队列中移除前端节点

    处理 Y 的所有邻居,对于 Y 的所有邻居 Z
    如果未访问 Z:
        Q.enqueue( Z ) // 将 Z 存储在 Q 中,
        将 Z 标记为已访问
按照下面的方法实现BFS遍历
  • 声明一个队列并插入起始顶点。
  • 初始化一个已访问数组并将起始顶点标为已访问。
  • 按照以下过程直到队列变空:
    - 删除队列的第一个顶点。
    - 将该顶点标记为已访问。
    - 将顶点的所有未访问邻居插入队列。

插图

step1:最初队列和访问数组都是空的。

队列和访问数组最初是空的

step2:将节点0推入队列并将其标记为已问。

将节点0推入队列并将其标记为已问。

step3:从队列的前面移除节点0并访问未访问的邻居并将它们推入队列。

从队列前面移除节点 0 并访问未访问的邻居并推入队列

step4: 从队列的前面移除节点1并访问未访问的邻居并将它们推入队列。

从队列的前面删除节点 1 并访问未访问的邻居并推送

setp5: 从队列的前面移除节点2并访问未访问的邻居并将它们推入队列。

从队列的前面删除节点 2 并访问未访问的邻居并将它们推入队列。

step6: 从队列的前面移除节点3并访问未访问的邻居并将它们推入队列。正如我们所看到的,节点3的每个邻居都被访问了,所以移动到队列前面的下一个节点。

从队列前面移除节点 3 并访问未访问的邻居并将它们推入队列

step7:从队列的前面移除节点4并访问未访问的邻居并将它们推入队列。

正如我们所看到的,节点4的每个邻居都被访问了,所以移动到队列前面的下一个节点。
从队列前面移除节点 4 并访问未访问的邻居并将它们推入队列。
现在,Queue 变空了,所以,终止这些迭代过程。

代码

// C++ code to print BFS traversal from a given
// source vertex

#include <bits/stdc++.h>
using namespace std;

// This class represents a directed graph using
// adjacency list representation
class Graph {

	// No. of vertices
	int V;

	// Pointer to an array containing adjacency lists
	vector<list<int> > adj;

public:
	// Constructor
	Graph(int V);

	// Function to add an edge to graph
	void addEdge(int v, int w);

	// Prints BFS traversal from a given source s
	void BFS(int s);
};

Graph::Graph(int V)
{
	this->V = V;
	adj.resize(V);
}

void Graph::addEdge(int v, int w)
{
	// Add w to v’s list.
	adj[v].push_back(w);
}

void Graph::BFS(int s)
{
	// Mark all the vertices as not visited
	vector<bool> visited;
	visited.resize(V, false);

	// Create a queue for BFS
	list<int> queue;

	// Mark the current node as visited and enqueue it
	visited[s] = true;
	queue.push_back(s);

	while (!queue.empty()) {
		
		// Dequeue a vertex from queue and print it
		s = queue.front();
		cout << s << " ";
		queue.pop_front();

		// Get all adjacent vertices of the dequeued
		// vertex s. If a adjacent has not been visited,
		// then mark it visited and enqueue it
		for (auto adjacent : adj[s]) {
			if (!visited[adjacent]) {
				visited[adjacent] = true;
				queue.push_back(adjacent);
			}
		}
	}
}

// Driver code
int main()
{
	// Create a graph given in the above diagram
	Graph g(4);
	g.addEdge(0, 1);
	g.addEdge(0, 2);
	g.addEdge(1, 2);
	g.addEdge(2, 0);
	g.addEdge(2, 3);
	g.addEdge(3, 3);

	cout << "Following is Breadth First Traversal "
		<< "(starting from vertex 2) \n";
	g.BFS(2);

	return 0;
}

输出结果

以下是广度优先遍历(从顶点2开始)
2 0 3 1
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值