图的遍历(广度优先搜索遍历)

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;
}

《图的遍历(广度优先搜索遍历)》

    原文作者:数据结构之图
    原文地址: https://blog.csdn.net/qq_22238021/article/details/78292105
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞