广度优先搜索算法

广度优先搜索算法

1.基本概念

BFS即从图中的某个顶点出发,将与该顶点相邻接且未被访问过的结点全部访问完,然后按照之前的访问顺序依次再访问它们自己的邻接结点,直到图中的所有已经被访问道的邻接结点都被访问到。如果此时还有结点没有被访问到,则选择该结点继续按照之前的方式进行访问。

如下图所示:


该广度优先搜索算法的遍历过程如下:


首先访问结点A,然后找到A的邻接结点B和C,访问这两个结点。然后从B出发,找到B的未被访问的结点邻接结点D和E,然后访问这两个结点,然后从结点C出发,找到C的未被访问的邻接结点F和G,然后访问这两个结点,然后从结点D出发,找到D的违背访问的邻接结点H,访问这个结点。然后从结点E出发…依此类推。

2.非递归实现

由于广度优先搜索需要记录某结点的所有未被访问的邻接结点,并且需要按照这些邻接结点的访问顺序获得邻接结点,因此在实现时需要用到队列。

其实现如下所示:

void BFSTraverse(ALGraph G){
	//非递归形式宽度优先访问树
	for(int i = 0; i<G.vertexNum; i++) visited[i] = false;
	queue<int> Q;

	for(int v = 0; v<G.vertexNum; v++){
		if(!visited[v]){
			visited[v] = true;
			cout<<"node: "<<G.vertices[v].data<<" ";
			Q.push(v);
			while(!Q.empty()){
				int u = Q.front();
				Q.pop();
				for(int w = FirstAdjVex(G,u); w>= 0; w = NextAdjVex(G, u, w)){
					if(!visited[w]){
						visited[w] = true;
						cout<<"node: "<<G.vertices[w].data<<" ";
						Q.push(w);
					}
				}
			}
		}
	}
}

测试全部代码如下所示:

扫描二维码关注公众号,回复: 162328 查看本文章
// BFS.cpp : Defines the entry point for the console application.
//


#include "stdafx.h"
#include <iostream>
#include <string>
#include <queue>
#include <stack>

#define MAX_VERTEX_NUM 20

using namespace std;

typedef int infoType;//弧信息
typedef char vertexType;//顶点保存字符信息
typedef int Status;

typedef struct ArcNode{
	int adjvex;
	struct ArcNode *nextArc;
	infoType *info;
}ArcNode;

typedef struct VertexNode{
	vertexType data;
	ArcNode *firstArc;
}VertexNode, AdjList[MAX_VERTEX_NUM];

typedef struct ALGraph{
	AdjList vertices;
	int vertexNum, arcNum;
	string kind;
}ALGraph;

int locateNode(ALGraph &G, VertexNode node){
	for(int i=0; i<G.vertexNum;i++){
		if(node.data == G.vertices[i].data)
			return i;
	}
	return -1;
}

void insertArcAction(ALGraph &G, int nodeNum1, int nodeNum2);
Status insertArc(ALGraph &G, VertexNode node1, VertexNode node2);

Status createGraph(ALGraph &G, string kind, int vertexNum, int arcNum){
	//采用邻接表构造图(有向或无向图)
	G.kind = kind;

	G.vertexNum = vertexNum;
	G.arcNum = arcNum;
	
	//初始化顶点信息
	for(int i = 0; i<G.vertexNum; i++){
		cin>>G.vertices[i].data;
		G.vertices[i].firstArc = NULL;
	}

	cout<<"Try to input arcs info"<<endl;
	for(int j = 0; j<G.arcNum; j++){
		cout<<"please input two nodes of "<<j+1<<"-th arc"<<endl;

		VertexNode node1, node2;
		cin>>node1.data>>node2.data;
		insertArc(G, node1, node2);
	}
	return 1;
}

void insertArcAction(ALGraph &G, int nodeNum1, int nodeNum2){
	ArcNode *p;
	ArcNode *arc;

	arc = new ArcNode[1];
	arc->adjvex = nodeNum2;

	p = G.vertices[nodeNum1].firstArc;//相当于链表的插入
	if(!p){
		G.vertices[nodeNum1].firstArc = arc;
		arc->nextArc = NULL;
	}
	else{
		G.vertices[nodeNum1].firstArc = arc;
		arc->nextArc = p;
	}
}

Status insertArc(ALGraph &G, VertexNode node1, VertexNode node2){
	int nodeNum1 = locateNode(G, node1);//i和j表示AdjList[MAX_VERTEX_NUM]中的位置
	int nodeNum2 = locateNode(G, node2);
	if(nodeNum1<0 || nodeNum2<0) exit(-1);
	
	if(G.kind == "DG")
		insertArcAction(G, nodeNum1, nodeNum2);
	else{
		insertArcAction(G, nodeNum1, nodeNum2);
		insertArcAction(G, nodeNum2, nodeNum1);
	}
	return 1;
}

Status printALGraph(ALGraph &G){
	for(int i = 0; i<G.vertexNum; i++){
		cout<<i<<" "<<G.vertices[i].data;
		ArcNode *arc = G.vertices[i].firstArc;

		while(arc){
			cout<<"-->"<<arc->adjvex;
			arc = arc->nextArc;
		}
		cout<<"-->NULL"<<endl;
	}
	return 1;
}

bool visited[MAX_VERTEX_NUM];

int FirstAdjVex(ALGraph G, int j){
	ArcNode *firstArc = G.vertices[j].firstArc;
	if(firstArc)
		return (firstArc->adjvex);
	else 
		return -1;
}

int NextAdjVex(ALGraph G, int j, int k){
	ArcNode *firstArc = G.vertices[j].firstArc;
	ArcNode *cur = firstArc;

	if(!firstArc)
		return -1;
	else{
		while(cur){
			if(cur->adjvex == k)
				break;
			cur = cur->nextArc;
		}
	}
	if(cur->nextArc)
		return (cur->nextArc->adjvex);
	else
		return -1;
}

void BFSTraverse(ALGraph G){
	//非递归形式宽度优先访问树
	for(int i = 0; i<G.vertexNum; i++) visited[i] = false;
	queue<int> Q;

	for(int v = 0; v<G.vertexNum; v++){
		if(!visited[v]){
			visited[v] = true;
			cout<<"node: "<<G.vertices[v].data<<" ";
			Q.push(v);
			while(!Q.empty()){
				int u = Q.front();
				Q.pop();
				for(int w = FirstAdjVex(G,u); w>= 0; w = NextAdjVex(G, u, w)){
					if(!visited[w]){
						visited[w] = true;
						cout<<"node: "<<G.vertices[w].data<<" ";
						Q.push(w);
					}
				}
			}
		}
	}
}

int _tmain(int argc, _TCHAR* argv[])
{
	ALGraph G;
	string kind = "UDG";
	int vertexNum = 9;
	int arcNum = 9;

	cout<<"Try to create a Adjacency list Graph ..."<<endl;
	createGraph(G, kind, vertexNum, arcNum);
	
	cout<<"Try to print a Adjacence list Graph ..."<<endl;
	printALGraph(G);

	cout<<"Try to traverse a undigraph in a regular form..."<<endl;//非递归
	BFSTraverse(G);
	cout<<endl;

	system("pause");
	return 0;
}


猜你喜欢

转载自blog.csdn.net/bible_reader/article/details/71436857