1、广度优先搜索遍历过程
(1)从某个顶点V出发,访问该顶点的所有邻接点V1,V2..VN
(2)从邻接点V1,V2…VN出发,再访问他们各自的所有邻接点
(3)重复上述步骤,直到所有的顶点都被访问过
若此时图中还有顶点未被访问,则在外控算法的控制下,另选一个未曾被访问的顶点作为起始点,重复上述过程,直到图中所有顶点都被访问完为止。
2、示例
对图7-28连通无向图广度优先搜索(以v0为出发点):v0,v1,v2,v3,v4,v5,v6,v7,v8
对图7-29非连通无向图广度优先搜索(以v0为出发点):v0,v1,v2,v3,v4,v5,v6,v7,v4为另一个起始点
对图7-30(a)有向图的广度优先搜索(v2为出发点):v2,v1,v3,v0,v4
对图7-30(b)有向图的广度优先搜索(v0为出发点):v0,v1,v4,v3,v2,v2为另一出发点
3、连通图的广度优先搜索遍历算法过程
基本思想:假设初始状态图中所有顶点未被访问,从图中某顶点v出发,访问它的所有邻接点w1,w2,…,wd,然后再依次访问w1,w2,…,wd的邻接点,直到所有与v有相通路 径的所有顶点都被访问完为止。
代码:
(1) 采用邻接矩阵从v出发广度优先搜索遍历连通图
#include <iostream>
using namespace std;
#define INFINITY 65535 /* 表示权值的无穷*/
typedef int EdgeType;//边上的权值类型
typedef int VertexType;//顶点类型
const int MaxSize=100;
int visited[MaxSize];//全局标识数组
class MGraph//邻接矩阵类
{
public:
MGraph(){vertexNum=0;edgeNum=0;}
MGraph(VertexType a[],int n);//构造函数,初始化具有n个顶点的零图
void CreateMGraph1(MGraph *Gp);//建立无向图的邻接矩阵
void BFS(int v);//从v出发广度优先遍历
public:
int vertexNum,edgeNum;//顶点数和边数
EdgeType adj[MaxSize][MaxSize];//邻接矩阵
VertexType vertex[MaxSize];//顶点表
};
//构造函数,初始化具有n个顶点的零图
MGraph::MGraph(VertexType a[],int n)
{
vertexNum=n;edgeNum=0;
for(int i=0;i<n;i++) vertex[i]=a[i];
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
adj[i][j]=0;
}
//建立无向图的邻接矩阵表示
void MGraph::CreateMGraph1(MGraph *Gp)
{
int i, j, k;
cout << "请输入顶点数和边数(空格分隔):" << endl;
cin >> Gp->vertexNum >> Gp->edgeNum;
cout << "请输入顶点信息(空格分隔):" << endl;
for (i = 0; i < Gp->vertexNum; i++)
cin >> Gp->vertex[i];
for (i = 0; i < Gp->vertexNum; i++)
{
for (j = 0; j < Gp->vertexNum; j++)
Gp->adj[i][j] = 0;
}
for (k = 0; k < Gp->edgeNum; k++)
{
cout << "请输入边(vi, vj)的上标i,下标j(空格分隔):" << endl;
cin >> i >> j;
Gp->adj[i][j] = 1;
Gp->adj[j][i] = 1;// 因为是无向图,矩阵对称
}
}
//从v出发广度优先搜索遍历连通图
void MGraph::BFS(int v)
{
int n=vertexNum,front,rear;
int Q[MaxSize];//队列
front=rear=-1;
if(v<0||v>=n) throw "位置出错";
cout<<vertex[v]<<" ";
visited[v]=1;
Q[++rear]=v;//被访问过的顶点进入队列
while(front!=rear)
{
v=Q[++front];//队列首元素出队列
for(int j=0;j<n;j++)
{
if(adj[v][j]==1&&visited[j]==0)
{
cout<<vertex[j]<<" ";
visited[j]=1;
Q[++rear]=j;
}
}
}
}
int main()
{
MGraph grph;
grph.CreateMGraph1(&grph);
for(int i=0;i<MaxSize;i++)
visited[i]=0;
for(int i=0;i<grph.vertexNum;i++)
{
for(int j=0;j<grph.vertexNum;j++)
{cout<<grph.adj[i][j]<<" ";}
cout<<endl;
}
cout<<"广度优先遍历结果:"<<endl;
grph.BFS(2);
return 0;
}
(2) 采用邻接表从v出发广度优先搜索遍历连通图
#include <iostream>
using namespace std;
#define INFINITY 65535 /* 表示权值的无穷*/
typedef int EdgeType;//边上的权值类型
typedef int VertexType;//顶点类型
const int MaxSize=100;
int visited[MaxSize];//全局标识数组
//无向图邻接表。边表结点结构
struct EdgeNode
{
int adjvex;//邻接点域
EdgeNode *next;//指向下一个边结点的指针
};
//无向图邻接表。表头结点结构
struct VexNode
{
VertexType vertex;//顶点
EdgeNode *firstedge;//边表的头指针
};
//邻接表类
class ALGraph
{
public:
ALGraph()//无参构造函数
{
vertexNum=0;
edgeNum=0;
for(int i=0;i<MaxSize;i++)
adjlist[i].firstedge=NULL;
}
ALGraph(VertexType a[],int n);//有参构造函数
void createGraph(int start, int end);//创建图,采取前插法
void BFSL(int v);//从v广度优先搜索
void displayGraph(int nodeNum);//打印
private:
VexNode adjlist[MaxSize];//存放顶点表的数组
int vertexNum,edgeNum;//图的顶点数和边数
};
//有参构造函数。构造顶点表
ALGraph::ALGraph(VertexType a[],int n)
{
vertexNum=n;
edgeNum=0;
for(int i=0;i<vertexNum;i++)
{
adjlist[i].vertex=a[i];
adjlist[i].firstedge=NULL;
}
}
//创建图,采取前插法
void ALGraph::createGraph(int start, int end)
{//边(start,end)
//adjlist[start].vertex=start;//表头结点中的顶点
EdgeNode *p=new EdgeNode;//边结点
p->adjvex=end;//邻接点
//p->weight=weight;
p->next=adjlist[start].firstedge;//前插法插入边结点p
adjlist[start].firstedge=p;
}
//打印存储的图
void ALGraph::displayGraph(int nodeNum)
{
int i,j;
EdgeNode *p;
for(i=0;i<nodeNum;i++)
{
p=adjlist[i].firstedge;
while(p)
{
cout<<'('<<adjlist[i].vertex<<','<<p->adjvex<<')'<<endl;
p=p->next;
}
}
}
//从v广度优先搜索
void ALGraph::BFSL(int v)
{
int n=vertexNum;
if(v>=n||v<0) throw "位置出错";
int front,rear,j;
int Q[MaxSize];//队列
front=rear=-1;//假设队列采用顺序存储,且不会发生溢出
EdgeNode *p;//边结点
cout<<adjlist[v].vertex<<" ";
visited[v]=1;
Q[++rear]=v;//被访问顶点进队列
while(front!=rear)
{
v=Q[++front];//队首元素出队列
p=adjlist[v].firstedge;//边表中的工作指针初始化
while(p)
{
j=p->adjvex;//顶点
if(visited[j]==0)
{
cout<<adjlist[j].vertex<<" ";
visited[j]=1;
Q[++rear]=j;//被访问顶点进队列
}
p=p->next;
}
}
}
int main()
{
int a[5]={0,1,2,3,4};
ALGraph gr=ALGraph(a,5);//初始化表头
gr.createGraph(0,1);
gr.createGraph(0,3);
gr.createGraph(1,0);
gr.createGraph(1,2);
gr.createGraph(2,1);
gr.createGraph(2,3);
gr.createGraph(2,4);
gr.createGraph(3,0);
gr.createGraph(3,2);
gr.createGraph(3,4);
gr.createGraph(4,2);
gr.createGraph(4,3);
cout<<"无向连通图各个边:"<<endl;
gr.displayGraph(5);
for(int i=0;i<MaxSize;i++)
visited[i]=0;
cout<<"广度优先遍历结果:"<<endl;
gr.BFSL(0);
return 0;
}