Figure (4)-Depth First Search BFS

1. The general idea of ​​breadth-first search:

    The breadth-first search method is shown in the figure below, which is opposite to DFS. BFS searches from top to bottom layer by layer.

2. This example also uses the following adjacency matrix

Three, the code and test results

#include <iostream>
#include <stack>
#include <queue>

using namespace std;


#define MAX_VERTEXS (20)



class Vertex   //顶点
{
public:
	Vertex(char lab) :label(lab)
	{
		isVisited = false;
	}

	//private:
	char label;
	bool isVisited; //true:访问过; flase:未被访问过
};

class Graph  //图 
{
public:
	Graph();
	~Graph();

	void addVertex(char lab);      //添加顶点
	void addEdge(int start, int end); //添加边
	void printMatrix();
	void showVertex(int index);

	void DFS();
	void BFS();

private:
	Vertex * vertexList[MAX_VERTEXS];  //用来保存加入进来的顶点
	int nVertexs;  //当前顶点的个数
	int adjMat[MAX_VERTEXS][MAX_VERTEXS]; //二维数组来表示顶点的连接方式

	int getNextUnvisitedVertex(int index); //获取下一个相邻的并且未访问的Vertex的index
										  //图中A连着B

};

Graph::Graph()
{
	nVertexs = 0;

	for (int i = 0; i < MAX_VERTEXS; i++)
		for (int j = 0; j < MAX_VERTEXS; j++)
			adjMat[i][j] = 0;
}
Graph::~Graph()
{
	for (int i = 0; i < nVertexs; i++)
		delete vertexList[i];
}

void Graph::addVertex(char lab)
{
	vertexList[nVertexs++] = new Vertex(lab);
}

void Graph::addEdge(int start, int end)
{
	adjMat[start][end] = 1;  //边是对称的
	adjMat[end][start] = 1;
}

void Graph::printMatrix()
{
	for (int i = 0; i < nVertexs; i++)
	{
		for (int j = 0; j < nVertexs; j++)
			cout << adjMat[i][j];

		cout << endl;
	}
}

void Graph::showVertex(int index)
{
	cout << vertexList[index]->label << " ";
}

int Graph::getNextUnvisitedVertex(int index)
{
	for (int i = 0; i < nVertexs; i++)
	{
		if ((adjMat[index][i] == 1) && (vertexList[i]->isVisited == false)) //找相邻的并且未访问的Vertex,返回下标
			return i;
	}

	return -1;
}

void Graph::DFS()
{
	stack<int> s; //这个堆的作用是用来存放Vertex的下标  (堆的特点,先进后出)

	s.push(0); //先把顶点放到堆中
	showVertex(0); //访问顶点           
	vertexList[0]->isVisited = true; //写成已访问
	int index = -1;

	while (s.size() > 0) //一直循环到堆中没有元素
	{
		index = getNextUnvisitedVertex(s.top());//获取堆最新Vertex的下一个未访问Vertex

		if (index < 0) //如果堆最新Vertex没有挨着的未访问Vertex了
		{
			s.pop();  //将其弹出
		}
		else    //访问这个Vertex
		{
			s.push(index);
			showVertex(index);
			vertexList[index]->isVisited = true;
		}

	}

	cout << endl;

	for (int i = 0; i < nVertexs; i++)
	{
		vertexList[i]->isVisited = false;
	}
}

void Graph::BFS(void)
{
	queue<int> q; //定义一个队列用来存放Vertex 的index

	q.push(0); //先把Vertex[0]放入到队列里
	showVertex(0);
	vertexList[0]->isVisited = true;
	int index1 =0, index2 = 0;

	while (q.size() > 0)  //当队列中还有数据的时候就一直循环
	{
		index1 = q.front(); //获取最前边
		q.pop(); //将其弹出
		index2 = getNextUnvisitedVertex(index1); //获取index1相邻的未被访问的元素

		while (index2 > 0)  //index1 不一定相邻一个元素,所以这里要循环,找到没有了为止
		{
			q.push(index2);
			showVertex(index2);
			vertexList[index2]->isVisited = true;

			index2 = getNextUnvisitedVertex(index1); //继续获取index1相邻的元素
		}
	}

	cout << endl;

	for (int i = 0; i < nVertexs; i++)
	{
		vertexList[i]->isVisited = false;
	}
}


int main()
{
	Graph gh;

	//添加顶点
	gh.addVertex('A');//0
	gh.addVertex('B');//1
	gh.addVertex('C');//2
	gh.addVertex('D');//3
	gh.addVertex('E');//4

	//添加边
	gh.addEdge(0, 1); //A-B
	gh.addEdge(0, 3); //A-D
	gh.addEdge(1, 0); //B-A
	gh.addEdge(1, 4); //B-E
	gh.addEdge(2, 4); //C-E
	gh.addEdge(3, 0); //D-A
	gh.addEdge(3, 4); //D-E
	gh.addEdge(4, 3); //E-D
	gh.addEdge(4, 2); //E-C

	gh.printMatrix();

	cout << endl;
	cout << "深度优先搜索结果: ";
	gh.DFS();

	cout << "广度优先搜索结果: ";
	gh.BFS();

	return 0;
}

 

Guess you like

Origin blog.csdn.net/weixin_40204595/article/details/109081506