B - 数据结构实验之图论二:图的深度遍历

Description
请定一个无向图,顶点编号从0到n-1,用深度优先搜索(DFS),遍历并输出。遍历时,先遍历节点编号小的。

Input
输入第一行为整数n(0 < n < 100),表示数据的组数。 对于每组数据,第一行是两个整数k,m(0 < k < 100,0 < m < k*k),表示有m条边,k个顶点。 下面的m行,每行是空格隔开的两个整数u,v,表示一条连接u,v顶点的无向边。

Output
输出有n行,对应n组输出,每行为用空格隔开的k个整数,对应一组数据,表示DFS的遍历结果。

Sample
Input
1
4 4
0 1
0 2
0 3
2 3
Output
0 1 2 3

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct {
    int vex[101];
    int arc[101][101];
    int vertex;//顶点
    int edges;//边数组
} MGraph;

int visited[101];//访问数组

int flag = 0; //作标记,使最后不输出空格
//DFS(图,起始顶点下标)
void DFS(MGraph G, int i) {
    visited[i] = 1; //标记起始顶点,表示已访问过
    if(flag == 0)
        printf("%d", G.vex[i]); //打印顶点
    else
        printf(" %d", G.vex[i]); //打印顶点
    flag = 1;
    /*
    从图中某个顶点i(顶点下标)出发,访问此顶点,然后从i的未被访问的邻接点出发深度优先遍历图,直至
    图中所有和i有路径相通的顶点都被访问到。事实上,我们这里讲到的是连通图,对于非连
    通图,只需要对它的连通分量分别进行深度优先遍历,即在先前一个顶点进行一次深度优
    先遍历后,若图中尚有顶点未被访问,则另选图中一个未曾被访问的顶点作起始点,重复
    上述过程,直至图中所有顶点都被访问到为止。
    */
    for(int j = 0; j < G.vertex; j++) {
        if(G.arc[i][j] == 1 && visited[j] == 0) {
            DFS(G, j); //找到邻接且没被访问的顶点,递归进行重复操作
        }
    }
}

//深度遍历函数
void DFSTraverse(MGraph G) {
    int i;
    for(i = 0; i < G.vertex; i++) {
        //(如果是连通图,只会执行一次if语句)
        if(visited[i] == 0){
            DFS(G, i); //对未访问的顶点调用DFS
        }
    }
    printf("\n");
}
int main() {
    int n;//数据组数
    int k;//顶点
    int m;//边
    int u, v; //表示一条连接u,v顶点的无向边。
    scanf("%d", &n);
    while(n--) {
        memset(visited,0,sizeof(visited));//访问数组初始化
        flag = 0;
        scanf("%d%d", &k, &m);
        MGraph G;
        G.vertex = k;//顶点数
        G.edges = m;//边数
        //给顶点赋值
        for(int i = 0; i < k; i++) {
            G.vex[i] = i;
        }
        //边关系初始化
        for(int i = 0; i < k; i++) {
            for(int j = 0; j < k; j++) {
                G.arc[i][j] = 0;
            }
        }
        //建立边关系
        for(int i = 0; i < m; i++) {
            scanf("%d%d", &u, &v);
            G.arc[u][v] = 1;
        }
        DFSTraverse(G);
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

夏至xz

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值