C++数据结构-邻接表的图的广度优先遍历BFS

#include <iostream>
#define MAXVEX 8 //起始顶点数默认为8,可在此直接修改
#define MAXEDGE 10 //起始边的数默认为10,可在此直接修改
using namespace std;

//该代码是无向图的邻接表的BFS
//注意点1:下标0的位置都不用,所以要多开辟一个空间
//注意点2:头结点信息既可以是字符A,B,C,D,也可以是字符'1','2'...
//注意点3:在创建邻接表时,使用头插法将边结点接在头结点之后

//将无向图的邻接表BFS改为有向图的邻接表BFS,则只要删去下面一段代码即可
//EdgeNode *s2 = new EdgeNode;
//s2->adjvex=m; //无向图现在n是头,m是尾
//s2->next = g.adjlist[n].firstedge;
//g.adjlist[n].firstedge=s2;

typedef struct EdgeNode
{
    int adjvex;
    struct EdgeNode *next;
}EdgeNode;               //边结点

typedef struct
{
    char vextexinfo;     //存放头结点信息(如A,B,C,D)
    EdgeNode *firstedge; //指向该结点的临边
}VextexNode,AdjList;     //头结点(即邻接表)

typedef struct
{
    int vexNum;                //顶点数
    int edgeNum;               //边数
    AdjList adjlist[MAXVEX+1]; //头结点数组
}ALGraph;

typedef struct
{
    int *datas;  //循环数组
    int rear;
    int head;
}Queue;          //队列

/****************初始化队列***********************/
void Initqueue(Queue &q)
{
    q.datas = new int[MAXVEX+1];
    q.head = q.rear=0;
}

/****************队列的插入(入队列)***********************/
void Insertqueue(Queue &q , int e)
{
    if((q.rear+1)%MAXVEX==q.head)
    {
        cout<<"队列已满!!!"<<endl;//实际此时还有一个空位
        return;
    }else
    {
        q.datas[q.rear] = e;
        q.rear=(q.rear+1)%MAXVEX;
    }
}

/****************队列的删除(出队列)***********************/
int Deletequeue(Queue &q)
{
    int e;
    e=q.datas[q.head];
    q.head=(q.head+1)%MAXVEX;
    return e;
}
/****************队列是否为空***********************/
int Emptyqueue(Queue &q)
{
    if(q.rear==q.head)
        return 0;
    else
        return 1;
}
/******************初始化邻接表*******************/
void InitAdjList(ALGraph &g)
{
    g.vexNum=MAXVEX;
    g.edgeNum=MAXEDGE;
    //初始化头结点数组(即表头信息)
    for(int i =1; i<=MAXVEX ; i++)
    {
        cout<<"请输入第"<<i<<"个结点的信息:";
        cin>>g.adjlist[i].vextexinfo;
        g.adjlist[i].firstedge=NULL; //初始化指针指向空
    }
}

//通过两个结点来确认边,并得到这两个结点的在数组的下标位置
/*********************确定邻接表数组下标的位置*********************/
void Locata(ALGraph &g,char &vex1,char &vex2, int &m, int &n)
{
    for(int i =1;i<=MAXVEX;i++)
    {
        if(vex1 == g.adjlist[i].vextexinfo)
            m=i;
        if(vex2 == g.adjlist[i].vextexinfo)
            n=i;
    }
}

/******************建立邻接表*******************/
void SetAdjList(ALGraph &g)
{
    char vex1,vex2;
    int m,n;
    for(int i=1;i<=MAXEDGE;i++) //有几条边就循环几次
    {
         cout<<"请输入第"<<i<<"条边(形如A B,表示A到B的一条边)";
         cin>>vex1>>vex2; //输入边的信息(即通过输入两顶点来确认边)
         Locata(g,vex1,vex2,m,n);//得到vex1和vex2在邻接表的数组下标位置m和n
         EdgeNode *s1 = new EdgeNode;
         s1->adjvex=n;   //无向图现在m是头,n是尾
         s1->next = g.adjlist[m].firstedge;
         g.adjlist[m].firstedge=s1;

         //要是将其改为有向图的邻接表,则,下面这段代码全部删除
         EdgeNode *s2 = new EdgeNode;
         s2->adjvex=m;   //无向图现在n是头,m是尾
         s2->next = g.adjlist[n].firstedge;
         g.adjlist[n].firstedge=s2;
    }
}
/******************显示邻接表*******************/
void ShowAdjList(ALGraph &g)
{
    cout<<"该图的邻接表如下:"<<endl;
    for(int i=1;i<=g.vexNum ;i++)
    {
        EdgeNode *p;
        cout<<"结点"<<i<<":";
        for(p = g.adjlist[i].firstedge; p!=NULL ; p=p->next)
            cout<<p->adjvex<<" ";
        cout<<endl;
    }
}
/*********************图的广度优先遍历BFS**************************/
void BFS(ALGraph &g ,int *visited, int v)  //从vex这个结点开始深度遍历图
{
    EdgeNode * p;
    int u , w;
    //创建队列
    Queue q;
    //初始化一个队列,队列长度为结点个数+1
    Initqueue(q);
    visited[v]=1;
    //只要结点未被访问就访问后将其存进队列里面
    Insertqueue(q,v);
    while(Emptyqueue(q) != 0)
    {
        u=Deletequeue(q);
        cout<<g.adjlist[u].vextexinfo<<"->"; //输出广度优先访问顺序
        p=g.adjlist[u].firstedge;
        while(p!=NULL)            //p非空说明顶点u存在邻接点
        {
            w=p->adjvex;
            if(visited[w] == 0)   //说明w未被访问
            {
                visited[w]=1;     //访问
                Insertqueue(q,w); //进队列
            }
            p=p->next; //p指向顶点u的下一个邻接点
        }
    }
}


int main()
{
    int visited[MAXVEX+1]={0}; //用来判断该结点是否被访问过,访问过为1,未访问则为0
    int v = 1;                 //表明该图是从下标为1的结点开始广度优先遍历的
    ALGraph g;
    InitAdjList(g);
    SetAdjList(g);
    ShowAdjList(g);
    BFS(g ,visited, v);
    return 0;
}

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