一.算法步骤
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;
}