数据结构与算法特训365天—广度优先搜索

一.算法步骤

1. 初始化图中所有顶点未被访问,初始化一个空队列;

2. 从图中的某个顶点v出发,访问v并标记已访问,将v入队;

3. 如果队列非空,则继续执行,否则算法结束;

4. 队头元素v出队,依次访问v的所有未被访问邻接点,标记已访问并入队。转向步骤3;

二.算法实现

2.1 基于邻接矩阵的广度优先遍历

#include <iostream>
#include <queue>
using namespace std;
#define MaxVnum 100  //顶点数最大值
bool visited[MaxVnum];  //访问标志数组,其初值为“false” 
typedef char VexType;  //顶点的数据类型,根据需要定义 //typedef:专门起外号的 
typedef int EdgeType;  //边上权值的数据类型,若不带权值的图,则为0或1
typedef struct{
	VexType Vex[MaxVnum];  //顶点数组 
	EdgeType Edge[MaxVnum][MaxVnum];  //二维数组 
	int vexnum,edgenum;  //顶点数,边数 
}AMGraph;

int locatevex(AMGraph G,VexType x)
{
	for (int i=0; i<G.vexnum; i++)  //查找顶点信息的下标 
		if(x==G.Vex[i])
			return i;
		return -1;  //没找到 
}

void CreateAMGraph(AMGraph &G) 
{
	int i,j;
	VexType u, v;
	cout<<"请输入顶点数:"<<endl;
	cin>>G.vexnum;
	cout<<"请输入边数:"<<endl;
	cin>>G.edgenum;
	cout<<"请输入顶点信息:"<<endl;
	for(int i=0; i<G.vexnum; i++)  //输入顶点信息,存入顶点信息数组
		cin>>G.Vex[i];
	for(int i=0; i<G.vexnum; i++)  //初始化邻接矩阵所有值为0,如果是网,则初始化为无穷大
	  for(int j=0; j<G.vexnum; j++)
	  	 G.Edge[i][j]=0;
	cout<<"请输入每条边依附的两个顶点:"<<endl;
	while(G.edgenum--)
	{
		cin>>u>>v;
		i=locatevex(G,u);  //查找顶点u的存储下标 
		j=locatevex(G,v);  //查找顶点v的存储下标 
		if(i!=-1&&j!=-1)
	      G.Edge[i][j]=G.Edge[i][j]=1;  //邻接矩阵储置1 
	    else
	    {
	    	cout<<"讨厌!你个大笨居输错了啦!!!"<<endl;
	    	G.edgenum++;  //本次输入不算 
		}
	}
}

void print(AMGraph G)  //输出邻接矩阵
{
	cout<<"图的邻接矩阵为:"<<endl;
	for(int i=0; i,G.vexnum; i++)
	{
		for(int j=0; j<G.vexnum; j++)
		 cout<<G.Edge[i][j]<<"\t";
		cout<<endl;
	} 
}

void BFS_AM(AMGraph G,int v)  //基于邻接矩阵的广度优先遍历
{
	int u,w;
	queue<int>Q;  //创建一个普通队列,里面存放int类型
	cout<<G.Vex[v]<<"\t";
	visited[v]=true;
	Q.push(v);
	while(!Q.empty())
	{
		u=Q.front();  //取出队头元素赋值给u 
		Q.pop();  //队头元素出队 
		for(w=0; w<G.vexnum; w++)  //依次检查u的所有邻接点 
		{
			if(G.Edge[u][w] && !visited[w])  //u、w邻接而w未被访问
			{
				cout<<G.Vex[v]<<"\t";
				visited[w]=true;
				Q.push(w);
			} 
		}
	} 
 }
 
int main()
{
	int v;
	VexType c; 
	AMGraph G;
	CreateAMGraph(G);
	print(G);
	cout<<"请输入连通图的起始点:"<<endl;
	cin>>c;
	v=locatevex(G,c); //查找顶点u的存储下标 
	if(v!=-1)
	{
		cout<<"深度优先搜索遍历连通图结果:"<<endl;
		BFS_AM(G,v); 
	}
	else
		cout<<"输出顶点信息出错!请重新输入!"<<endl;
	return 0;
}

2.2 基于邻接表的广度优先遍历

#include <iostream>
#include <queue>
using namespace std;
const int MaxVnum=100;  //顶点数最大值
bool visited[MaxVnum];  //访问标志数组,其初值为“false”

typedef char VexType;  //顶点的数据类型为字符型
typedef struct AdjNode{  //定义邻接点类型
	int v;
	struct AdjNode *next;  //指向下一个邻接点 
}AdjNode;

typedef struct VexNode{  //定义定点类型 
	VexType data;  //VerType为顶点的数据类型,根据需要定义 
	AdjNode *first;  //指向第一个邻接点 
}VerNode;

typedef struct{  //定义邻接表类型
	VexNode Vex[MaxVnum];
	int vexnum,edgenum;  //顶点数,边数 
}ALGraph;

int locatevex(ALGraph G,VexType x)
{
	for(int i=0; i<G.vexnum; i++)
		if(x==G.Vex[i].data)
		return i;
	return -1;  //没找到 
}

void insertedge(ALGraph &G, int i, int j)  //头插法插入一条边 
{
	AdjNode *s;
	s=new AdjNode;
	s->v-j;
	s->next=G.Vex[i].first;
	G.Vex[i].first=s;
}

void print(ALGraph G)  //输出邻接表
{
	cout<<"------邻接表如下------"<<endl;
	for(int i=0; i<G.vexnum; i++)
	{
		AdjNode *t=G.Vex[i].first;
		cout<<cout<<G.Vex[i].data<<":";
		while(t!=NULL)
		{
			cout<<"["<<t->v<<"] ";
			t=t->next;
		}
		cout<<endl;
	} 
} 

void CreateALGraph(ALGraph &G)  //创建有向图邻接表
{
	int i,j;
	VexType u,v;
	cout<<"请输入顶点数和边数:"<<endl;
	cin>>G.vexnum>>G.edgenum;
	cout<<"请输入顶点信息:"<<endl;
	for(i=0; i<G.vexnum; i++)  //输入顶点信息,存入顶点信息数组
		cin>>G.Vex[i].data;
	for(i=0; i<G.vexnum; i++)
		G.Vex[i].first=NULL;
	cout<<"请依次输入每条边的两个顶点u,v"<<endl;
	while(G.edgenum--)
	{
		cin>>u>>v;
		i=locatevex(G,u);  //查找顶点u的存储下标 
		j=locatevex(G,v);  //查找顶点v的存储下标 
		if(i!=-1&&j!=-1)
			insertedge(G,i,j);
		else
		{
			cout<<"输入顶点信息错!请重新输入!"<<endl;
			G.edgenum++;//本次输入不算 
		}
	} 
} 

void BFS_AL(ALGraph G,int v)  //基于邻接矩阵的广度优先遍历
{
	int u,w;
	AdjNode *p;
	queue<int>Q;  //创建一个普通队列,里面存放int类型
	cout<<G.Vex[v].data<<"\t";
	visited[v]=true;
	Q.push(v);
	while(!Q.empty())
	{
		u=Q.front();  //取出队头元素赋值给u 
		Q.pop();  //队头元素出队
		p=G.Vex[u].first;
		while(p)  //依次检查u的所有邻接点 
		{
			w=p->v;  //w为u的邻接点 
			if(visited[w])  //w未被访问 
			{
				cout<<G.Vex[w].data<<"\t";
				visited[w]=true;
				Q.push(w);
			}
			p=p->next;
		}
	} 
 } 
 
void BFS_AL(ALGraph G)  //非连通图,基于邻接表的广度优先遍历 
{
	for(int i=0; i<G.vexnum; i++)  //非连通图需要查找漏点,检查未被访问的点 
	if(!visited[i])  //i未被访问,以i为起点再次广度优先遍历 
	   BFS_AL(G,i);
 } 

int main()
{
	ALGraph G;
	int v;
	VexType c; 
	CreateALGraph(G);
	print(G);
	cout<<"请输入连通图的起始点:"<<endl;
	cin>>c;
	v=locatevex(G,c); //查找顶点u的存储下标 
	if(v!=-1)
	{
		cout<<"深度优先搜索遍历连通图结果:"<<endl;
		BFS_AL(G,v); 
	}
	else
		cout<<"输出顶点信息出错!请重新输入!"<<endl;
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值