25. 图的广度优先遍历

1 描述

本实验实现邻接表表示下无向图的广度优先遍历。

程序的输入是图的顶点序列和边序列(顶点序列以*为结束标志,边序列以-1,-1为结束标志)。程序的输出为图的邻接表和广度优先遍历序列。例如:

程序输入为:
a
b
c
d
e
f
*
0,1
0,4
1,4
1,5
2,3
2,5
3,5
-1,-1

程序的输出为:
the ALGraph is
a 4 1
b 5 4 0
c 5 3
d 5 2
e 1 0
f 3 2 1
the Breadth-First-Seacrh list:aebfdc

 测试输入 期待的输出 时间限制 内存限制 额外进程
测试用例 1以文本方式显示
  1. a↵
  2. b↵
  3. c↵
  4. d↵
  5. e↵
  6. f↵
  7. *↵
  8. 0,1↵
  9. 0,4↵
  10. 1,4↵
  11. 1,5↵
  12. 2,3↵
  13. 2,5↵
  14. 3,5↵
  15. -1,-1↵
以文本方式显示
  1. the ALGraph is↵
  2. a 4 1↵
  3. b 5 4 0↵
  4. c 5 3↵
  5. d 5 2↵
  6. e 1 0↵
  7. f 3 2 1↵
  8. the Breadth-First-Seacrh list:aebfdc↵
1秒64M0

2 解题

代码

/* scanf读取单个字符时不会遇到换行符停止,
但不会清空缓冲区的换行符,下一读取的字符是换行符,多个字符读取时没有这个情况*/
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <queue>
using namespace std;
const int N = 100;

typedef struct vexnode
{
    char ch;  //顶点的字母
    int index;  //给顶点编号,处理数字更方便
    int visited;  //标记是否已经访问
} NODE;

typedef struct edgenode
{
    int to;  //邻接表
    int next;
} EDGE;

NODE vertex[N];
EDGE edge[N];
int cnt = 0;  //邻接表下标
int head[N];
int vextotal = 0;
queue<int> q;

// 把邻接表存储在一维数组里面
void CreatEdgelist(int x, int y)
{
    edge[cnt].to = y;
    edge[cnt].next = head[x];  //初始值是-1
    head[x] = cnt++;  //存的是第i个元素的第一个邻接点在一维数组中的位置的下标
    //因为是无向图,x->y就有y->x,所以两个信息都要存储
    edge[cnt].to = x;
    edge[cnt].next = head[y];
    head[y] = cnt++;
}

void PrintGraph()
{
    printf("the ALGraph is\n");
    for(register int i = 0; i < vextotal; i++) {
        printf("%c", vertex[i].ch);
        for(register int j = head[i]; j != -1; j = edge[j].next) {
            printf(" %d", edge[j].to);
        }
        printf("\n");
    }
}

// bfs和dfs都只能遍历连通图
void BFS(int curr)
{
    if(vertex[curr].visited == 1)
        return;
    q.push(curr);
    vertex[curr].visited = 1;
    while(!q.empty()) {
        curr = q.front();
        q.pop();
        printf("%c", vertex[curr].ch);
        for(register int i = head[curr]; i != -1; i = edge[i].next) {  // i是数组edge中的下标
            register int j = edge[i].to;
            if(vertex[j].visited != 1) {
                q.push(j);
                vertex[j].visited = 1;  //进入队列的时候就要做好标记,不然会重复进入
            }
        }
    }
}

// 避免没有路径的顶点被遗忘
void Traverse()
{
    printf("the Breadth-First-Seacrh list:");
    for(register int i = 0; i < vextotal; i++)
        BFS(i);
    printf("\n");
}

int main(int argc, char* argv[])
{
    char input;
    int i;
    int x, y;

    // freopen("file in.txt", "r", stdin);
    scanf("%c", &input);
    for(i = 0; input != '*'; i++) {
        vertex[i].ch = input;
        vertex[i].index = i;
        vertex[i].visited = -1;  //不使用0,有0可能是下标
        head[i] = -1;  //初始化
        getchar();
        scanf("%c", &input);  //这时候scanf读取的是回车键,增加一个getchar()
    }
    vextotal = i;
    scanf("%d,%d", &x, &y);
    while(x != -1 && y != -1) {
        CreatEdgelist(x, y);
        scanf("%d,%d", &x, &y);  //这个scanf并不会读取后面的换行符
    }
    PrintGraph();
    Traverse();

    return 0;
}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值