深度优先遍历的思想:
首先以一个未被访问过的顶点作为起始顶点,沿当前顶点的边走到未访问的顶点:
当没有未访问过的顶点时,则回到上一个顶点,继续试探别的顶点,直到所有的顶点都被访问过。
深度优先遍历时沿着图的某一条分支遍历直到末端,然后回溯,再沿着另一条进行同样的遍历,直到所有的点都被遍历过为止
这是遍历,而不是走一个通路
需要把所有的点都进行访问
#include<stdio.h>
int book[101]; //book用于记录顶点i是否被访问过
int sum, n;
int e[101][101]; //图的存储
void dfs(int cur)
{
int i;
printf("%d ", cur); //访问了这个顶点cur
sum++; //每访问一个顶点,sum就+1
if (sum == n) //如果已经遍历完所有点,直接退出
return;
for (i = 1; i <= n; i++)
{
//判断从点cur到i是否有路,且i没有被访问过
if (e[cur][i] == 1 && book[i] == 0)
{
book[i] = 1; //标记i点,表示已被访问
dfs(i); //访问i点
}
}
return;
}
int main()
{
int i, j, m, a, b;
scanf("%d%d", &n, &m); //n表示有多少个点,m表示有多少条边
for (i = 1; i <= n; i++)
{
for (j = 1; j <= n; j++)
{
if (i == j)
e[i][j] = 0; //自己到自己
else
e[i][j] = 10000000; //无穷表示没有边
}
}
for (i = 1; i <= m; i++) //输入边
{
scanf("%d%d", &a, &b); //表示a,b点有边
e[a][b] = 1; //在e中存储a,b两点之间有边
e[b][a] = 1; //因为是无向图,因此在a,b和b,a都存储一次
}
book[1] = 1; //从1顶点开始遍历
dfs(1);
return 0;
}
广度优先遍历的思想:
首先以一个未被访问过的顶点作为起始顶点,访问其所有相邻的顶点,然后对每个相邻的顶点,再访问它们相邻的未被访问过的顶点,直到所有顶点都被访问过,遍历结束。
广度优先遍历的根本在于队列
#include<stdio.h>
int book[101] = { 0 }; //存储该点是否已经被访问
int e[101][101]; //存储图
int que[10000]; //表示表示一个队列
int head, tail; //队首与队尾
int main()
{
int i, j, n, m, a, b, cur;
scanf("%d%d", &n, &m);
for (i = 1; i <= n; i++) //初始化
{
for (j = 1; j <= n; j++)
{
if (i == j)
e[i][j] = 0; //自身与自身无边
else
e[i][j] = 10000000;
}
}
for (i = 1; i <= m; i++) //输入边
{
scanf("%d%d", &a, &b);
e[a][b] = 1; //无向,存两次
e[b][a] = 1;
}
//队列初始化
head = 1;
tail = 1;
//从1号顶点出发
que[tail] = 1; //将1号顶点加入队列中
tail++; //队尾标志后移,队尾标志指向队尾元素的后一个位置
book[1] = 1; //标记1号顶点已经被访问
while (head < tail)
{
cur = que[head];
for (i = 1; i <= n; i++)
{
//遍历每一个点,看当前点与下一个点是否有通路且下一个点还没有被访问过
if (e[cur][i] == 1 && book[i] == 0)
{
que[tail] = i; //加入队列
tail++;
book[i] = 1;
}
if (tail > n) //总共n个点,已经访问了n个了,自然退出
{
break;
}
}
head++; //队列队首++
}
for (i = 1; i < tail; i++) //按照访问顺序输出
{
printf("%d ", que[i]);
}
return 0;
}
图的存储
图的邻接矩阵存储法
使用一个二维数组e来存储
<i, j> == 1,表示顶点i到顶点j之间有边
<i, j> == ∞,表示顶点i到顶点j之间无边
<i, i> == 0,表示自己到自己为0
无向图,使用图的邻接矩阵法,矩阵是沿对角线对称的
for (i = 1; i <= m; i++) //输入边
{
scanf("%d%d", &a, &b); //表示a,b点有边
e[a][b] = 1; //在e中存储a,b两点之间有边
e[b][a] = 1; //因为是无向图,因此在a,b和b,a都存储一次
}
5155

被折叠的 条评论
为什么被折叠?



