図(4)-深さ優先探索BFS

1.幅優先探索の一般的な考え方:

    幅優先探索方法を次の図に示します。これはDFSの反対です。BFSはレイヤーごとに上から下に検索します。

2.この例では、次の隣接行列も使用しています

3つ目は、コードとテスト結果です。

#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;
}

 

おすすめ

転載: blog.csdn.net/weixin_40204595/article/details/109081506