图的深度及广度搜索

今天来学习下,图的遍历方法,我们以下面这个图为例。
图
开始之前呢,先说个题外话,我们用最常用的二维数组来存这个图,专业的叫法是邻接矩阵法,这好像不是题外话吧!!^_^要不要先自己想一下,上面这个图用邻接矩阵怎么存呢!
废话不多说,先来个深度的吧:
那什么叫深度搜索呢:以一个未访问过的顶点(图由顶点和边组成,不要说你不知道哦!)为起点,沿着当前顶点边走到未访问过的顶点,当没有未访问过的顶点时,回到该顶点的上一个顶点,继续走到其未访问过的顶点,直到所有顶点都被访问过。对文字不太感冒?来看下面的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;
}

是不是很容易?多多体会吧!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值