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