数据结构实验之图论二:基于邻接表的广度优先搜索遍历

来源:互联网 发布:好看的电视剧 知乎 编辑:程序博客网 时间:2024/06/11 16:03

数据结构实验之图论二:基于邻接表的广度优先搜索遍历


Problem Description

给定一个无向连通图,顶点编号从0到n-1,用广度优先搜索(BFS)遍历,输出从某个顶点出发的遍历序列。(同一个结点的同层邻接点,节点编号小的优先遍历)

Input

输入第一行为整数n(0< n <100),表示数据的组数。
对于每组数据,第一行是三个整数k,m,t(0<k<100,0<m<(k-1)*k/2,0< t<k),表示有m条边,k个顶点,t为遍历的起始顶点。
下面的m行,每行是空格隔开的两个整数u,v,表示一条连接u,v顶点的无向边。

Output

输出有n行,对应n组输出,每行为用空格隔开的k个整数,对应一组数据,表示BFS的遍历结果。

Example Input

16 7 00 30 41 41 52 32 43 5

Example Output

0 3 4 2 5 1

Hint

用邻接表存储。


解题思路
代码1:这道题耗费了很长时间,起初我对邻接表结构体的定义充满了疑惑,在做题过程中总共建立了三个结构体分别用来存放头结点,表结点,邻接表的信息。
代码2:用队列。
代码3:借助vector容器,大幅减少了代码量,且思路清晰,易懂。这里就不多做解释了。日后补上代码


代码1

#include <stdio.h>#include <stdlib.h>#define MVNum 100//最大顶点数typedef struct ArcNode//边结点{    int adjvex;//该边所指向的顶点的位置    struct ArcNode *nextarc;//指向下一条边的指针   // int info;//和边相关的信息(这里一般是用来存放权值的)}ArcNode;typedef struct VNode//顶点信息{    int data;    ArcNode *firstarc;//指向第一条依附该顶点边的指针(指向ArcNode结构体的变量)}VNode,AdjList[MVNum];//AdjList表示邻接表类型typedef struct{//邻接表    AdjList vertices;//数组名    int vexnum,arcnum;//vexnum:图的当前顶点数  arcnum:边数}ALGraph;ALGraph G;int t,visited[100],q[100];void BFS(int t){    ArcNode *p;    int front=0,rear=0;    visited[t]=1;    printf("%d",t);    q[rear++]=t;    while(front!=rear)    {        int f,i;        f=q[front++];        p=G.vertices[f].firstarc;        while(p)        {            if(!visited[p->adjvex])            {                visited[p->adjvex]=1;                printf(" %d",p->adjvex);                q[rear++]=p->adjvex;            }            p=p->nextarc;        }    }}int main(){    int n;    scanf("%d",&n);    while(n--)    {        int i;        scanf("%d%d%d",&G.vexnum,&G.arcnum,&t);        //vexnum:图的当前顶点数  arcnum:边数   t为遍历的起始顶点        for(i=0;i<G.vexnum;i++)//初始化头结点        {            G.vertices[i].data=i;            G.vertices[i].firstarc=NULL;        }        int u,v;        ArcNode *s,*p,*pre;        for(i=0;i<G.arcnum;i++)//建邻接表        {            scanf("%d%d",&u,&v);            s=(ArcNode*)malloc(sizeof(ArcNode));            s->adjvex=v;            p=G.vertices[u].firstarc;            if(!p)            {                s->nextarc = NULL;                G.vertices[u].firstarc = s;            }            else{                 //pre = p;                 while(p)                 {                    if(p->adjvex>v)                        break;                    pre = p;                    p=p->nextarc;                 }                 s->nextarc = pre->nextarc;                 pre->nextarc = s;            }            s=(ArcNode*)malloc(sizeof(ArcNode));            s->adjvex=u;            p=G.vertices[v].firstarc;            if(!p)            {                s->nextarc = NULL;                G.vertices[v].firstarc = s;            }            else{                 //pre = p;                 while(p)                 {                    if(p->adjvex>u)                        break;                    pre = p;                    p=p->nextarc;                 }                 s->nextarc = pre->nextarc;                 pre->nextarc = s;            }            /*            if(!p||p->info>v)            {                s->nextarc=G.vertices[u].firstarc;                G.vertices[u].firstarc=s;            }else{                while(p->nextarc&&p->nextarc->info<v)                    p=p->nextarc;                s->nextarc=p->nextarc;                p->nextarc=s;            }            s=(ArcNode*)malloc(sizeof(ArcNode));            s->info=u;            p=G.vertices[v].firstarc;            if(!p||p->info>u)            {                s->nextarc=G.vertices[v].firstarc;                G.vertices[u].firstarc=s;            }else{                while(p->nextarc&&p->nextarc->info<u)                    p=p->nextarc;                s->nextarc=p->nextarc;                p->nextarc=s;            }*/        }        memset(visited,0,sizeof(visited));        BFS(t);    }}

代码2
用队列来做的

#include<iostream>#include<cstdio>#include<queue>#include<cstring>using namespace std;priority_queue<int ,vector<int>,greater<int> >pque[102];/*这个是STL提供的一种定义方法,也就是“越小的整数优先级越大的优先队列”的一种定义方法*/int visit[102],T;//visit是标记数组queue<int>temp;void BFS(int key){    temp.push(key);    while(!temp.empty())//一直访问到空为止    {        int b=temp.front();        if(visit[b])            temp.pop();        else        {            if(T)//标记打印,以免出现格式错误                printf(" %d",b);            else            {                printf("%d",b);                T=1;            }            visit[b]=1;            temp.pop();            while(!pque[b].empty())//不断地将与该点相关的点弹出            {                int a=pque[b].top();                temp.push(a);                pque[b].pop();            }        }    }}int main(){    int n;    cin>>n;    while(n--)    {        memset(visit,0,sizeof(visit));//初始化        int k,m,t;        cin>>k>>m>>t;        for(int i=0; i<k; i++)//初始化,就是清空队列            while(!pque[i].empty())                pque[i].pop();        while(m--)//这里是输入        {            int a,b;            cin>>a>>b;            pque[a].push(b);            pque[b].push(a);        }        T=0;        BFS(t);        printf("\n");    }    return 0;}
阅读全文
0 0