今天来学习下,图的遍历方法,我们以下面这个图为例。
开始之前呢,先说个题外话,我们用最常用的二维数组来存这个图,专业的叫法是邻接矩阵法,这好像不是题外话吧!!^_^要不要先自己想一下,上面这个图用邻接矩阵怎么存呢!
废话不多说,先来个深度的吧:
那什么叫深度搜索呢:以一个未访问过的顶点(图由顶点和边组成,不要说你不知道哦!)为起点,沿着当前顶点边走到未访问过的顶点,当没有未访问过的顶点时,回到该顶点的上一个顶点,继续走到其未访问过的顶点,直到所有顶点都被访问过。对文字不太感冒?来看下面的include的吧
#include<stdio.h>
#define N 10
//图的邻接矩阵
int map[N+1][N+1];
//一个顶点到底访问过没,用这个数组帮忙
//访问过用1表示,反之用0
int visit[N+1];
/*cur 当前顶点 */
int sum;//当前访问过的顶点个数
int n,m;//图的顶点个数和边的个数
void DFS(int cur){
printf("%d ",cur);//打印当前顶点号
sum++;
if(sum==n){
return;
}
for(int i=1;i<=n;i++){
//当前顶点到第i号顶点有路可走,并且没有被访问过
if(map[cur][i]==1 && visit[i]==0){
visit[i]=1;//标记i号顶点访问过
DFS(i);//从当前顶点再出发
}
}
return;
}
int main(){
int a,b,i,j;
scanf("%d%d",&n,&m);//读入图的顶点数和边数
for(i=1;i<=n;i++){
for(j=1;j<=n;j++){
if(i==j){
map[i][j]=0;//自身到自身是可以到达的
}else{
map[i][j]=999999;//表示不可到达
}
}
}
for(i=1;i<=m;i++){
scanf("%d%d",&a,&b);
map[a][b]=1;
map[b][a]=1;
}
visit[1]=1;
DFS(1);
return 0;
}
趁热打铁,接着我们来看看广度搜索。
何为广度搜索呢,它的思想是这样的:首先以一个未访问过的顶点作为起点,访问其所有可以到达的顶点,再以每个可以到达的顶点,访问其所有可以到达的顶点,知道图中所有顶点都被访问过。下面来看看具体的代码实现:
#include<stdio.h>
#define N 10
int que[N*N];
int map[N+1][N+1];
int visit[N+1];
int n,m;
/*小提示:广度搜索是要借助于队列*/
void BFS(){
int head,tail;
//初始化队列
head = tail = 1;
que[tail]=1;
tail++;
visit[1]=1;
while(head<tail){
//遍历每一个顶点
for(int i=1;i<=n;i++){
//若从当前顶点可以到达 顶点 i,并且顶点 i 没有访问过
if(map[que[head]][i]==1 && visit[i]==0){
que[tail]=i;
visit[i]=1;
tail++;
}
//当队列中有n个顶点时,说明图的顶点都遍历完毕
if(tail>n){
break;
}
}
head++;
}
for(int i=1;i<tail;i++){
printf("%d ",que[i]);
}
}
int main(){
int i,j,a,b;
//读入顶点个数,边的条数
scanf("%d%d",&n,&m);
//图的初始化
for(i=1;i<=n;i++){
for(j=1;j<=n;j++){
if(i==j)
map[i][j]=0;//自身可以到达
else
map[i][j]=999999;//表示不可以到达
}
}
//读入边的信息
for(i=1;i<=m;i++){
scanf("%d%d",&a,&b);
map[a][b]=map[b][a] = 1;//表示可以到达
}
BFS();
return 0;
}
是不是很容易?多多体会吧!