C++之广度优先搜索(BFS)

对树的遍历中,我们学过前序遍历,中序遍历,后序遍历。图是一种特殊的树,因此图的遍历就是由树的遍历而演变过来的。图有两中遍历的算法:广度优先搜索(BFS) 深度优先搜索(DFS)。今天我们先来学习一下广度优先搜索吧。学习深度优先搜索,请参考我的另一篇博客。

广度优先算法的思想:给定源顶点s,然后搜索与s所邻接的顶点,然后再搜索s邻接顶点的邻接顶点,以次下去,直到搜索到所有的顶点。该思想就是树的层序遍历的演变,一层一层的进行遍历,因此构成了广度优先树

该搜索算法之所以称为广度优先搜索,是因为它始终是将已发现和未发现的顶点之间的边界,沿其广度方向向外扩展,也就是呈一种发散状向外边扩散。算法首先会发现和s距离为k的顶点,然后才发生和s距离为k+1的顶点。

算法的时间复杂度:首先要对每个顶点要进行访问,其时间复杂度为O(|V|),每个顶点要对外进行发散,也就是对每个边进行了访问,其时间复杂度为O(|E|),所以算法的时间复杂度为O(|V|+|E|)

#include<iostream>
#include<list>
#include<queue>
#include<memory>
typedef size_t VERTEXN;
typedef bool KNOW;
struct Vertex {
	VERTEXN vertexnumber;
	KNOW*   visited; //存储该顶点的访问情况
};
class Graph {
public:
	Graph(const size_t _vertexnumber) :vertex(std::make_unique<Vertex>()), lists(new std::list<size_t>[_vertexnumber]()), queu(new std::queue<size_t>[_vertexnumber]()) {
		vertex->visited = new bool[_vertexnumber]();
		vertex->vertexnumber = _vertexnumber;
	}
	~Graph() {
		if (vertex && lists && queu && vertex->visited) {
			delete[] lists;
			delete[] queu;
			delete[] vertex->visited;
		}
		else
			throw std::out_of_range("Out of MemorySpace");
	}
	void AddEdge(const size_t v, const size_t w);
	void BFS(size_t v);
private:
	std::unique_ptr<Vertex>vertex;
	std::list<size_t>*lists; //邻接表
	std::queue<size_t>*queu;
};

void Graph::AddEdge(const size_t v, const size_t w) {
	lists[v].push_back(w);
}

void Graph::BFS(size_t v) {
	vertex->visited[v] = true;
	queu->push(v);
	while (!queu->empty()) {
		 v= queu->front();
		std::cout << v << std::endl;
		queu->pop();
		auto beg = lists[v].begin();
		while (beg != lists[v].end()) {
			if (!(vertex->visited[*beg])) {
				vertex->visited[*beg] = true;
				queu->push(*beg);
			}
			++beg;
		}
	}
}

int main(void)
{
	const size_t indegreenumber = 7;
	Graph graph(indegreenumber);
	graph.AddEdge(0, 1);
	graph.AddEdge(0, 2);
	graph.AddEdge(0, 3);
	graph.AddEdge(1, 3);
	graph.AddEdge(1, 4);
	graph.AddEdge(2, 5);
	graph.AddEdge(3, 2);
	graph.AddEdge(3, 5);
	graph.AddEdge(3, 6);
	graph.AddEdge(3, 4);
	graph.AddEdge(4, 6);
	graph.AddEdge(6, 5);
	graph.BFS(0);

	system("pause");
	return 0;
}

 

这时有人会提问?如果图为无向图怎么办呢?很简单呢,只要改变一下AddEdge()即可。

void Graph::AddEdge(const size_t v, const size_t w) {
	lists[v].push_back(w);
	lists[w].push_back(v);
}

这时有人又会提问?在有向图中,如果存在从某个顶点无法搜索所有的顶点,那怎么办呢?我们可以对每个未搜索顶点进行BFS就可以啦~ 

void Graph::BFSS() {
	for (int i = 0; i < vertex->vertexnumber; ++i) {
		if (!vertex->visited[i])
			BFS(i);
	}
}

参考:《算法导论》

发布了50 篇原创文章 · 获赞 11 · 访问量 4086

猜你喜欢

转载自blog.csdn.net/qq_43145594/article/details/103139496