图的广度优先遍历

这篇博客介绍了广度优先遍历(BFS)的概念,并通过C++代码展示了如何在基于邻接矩阵和邻接表的图结构中实现BFS。文中提供了创建图、输出图以及进行BFS遍历的完整过程,同时给出了两种数据结构下的示例代码。测试数据用于验证代码的正确性。
摘要由CSDN通过智能技术生成

广度优先遍历(Breadth First Search BFS)又被称为宽度优先搜素。
如下图
在这里插入图片描述
假设源点为1,从1出发访问1的邻接点2、3,从2出发访问4,从3出发访问5,从4出发访问6,访问完毕。

基于邻接矩阵的广度优先代码:

#include<iostream>
#include<queue>//引入队列头文件
using namespace std;
const int MaxVnum=100;//顶点数最大值
bool visited[MaxVnum];  //访问标志数组,其初值为"false"
typedef char VexType;  //顶点的数据类型,根据需要定义
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]=1; //邻接矩阵储置1,若无向图G.Edge[i][j]=G.Edge[j][i]=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); //源点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[w]<<"\t";
            	visited[w]=true;
            	Q.push(w);
            }
        }
    }
}

int main(){
    int v;
    VexType c;
    AMGraph G;
    CreateAMGraph(G);
    print(G);
    cout << "请输入遍历图的起始点:";
	cin>>c;
	v=locatevex(G,c);//查找顶点u的存储下标
    if(v!=-1){
        cout<<"广度优先搜索遍历图结果:"<<endl;
        BFS_AM(G,v);
    }
    else
        cout<<"输入顶点信息错!请重新输入!"<<endl;
    return 0;
}
/*测试数据
6 9
1 2 3 4 5 6
1 3
1 2
2 4
3 5
3 2
4 6
4 3
5 6
5 4
1
*/ 

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

#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; // VexType为顶点的数据类型,根据需要定义
	AdjNode *first; //指向第一个邻接点
}VexNode;

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 printg(ALGraph G){//输出邻接表
	cout<<"----------邻接表如下:----------"<<endl;
	for(int i=0;i<G.vexnum;i++){
		AdjNode *t=G.Vex[i].first;
		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); //源点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);//创建有向图邻接表
    printg(G);//输出邻接表
    cout<<"请输入遍历图的起始点:";
	cin>>c;
	v=locatevex(G,c);//查找顶点u的存储下标
    if(v!=-1){
        cout<<"广度优先搜索遍历图结果:"<<endl;
        BFS_AL(G,v);
    }
    else
        cout<<"输入顶点信息错!请重新输入!"<<endl;
    return 0;
}
/*测试数据
6 9
1 2 3 4 5 6
1 3
1 2
2 4
3 5
3 2
4 6
4 3
5 6
5 4
1
*/ 
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值