数据结构-无权无向图-深度优先搜索(递归)

注:采用邻接矩阵递归的算法,在前面的博文中有非递归算法,包括邻接表的深搜 。

数据结构-图-深度优先遍历-CSDN博客

Description
利用深度优先搜索算法,对给定无向图进行深度优先搜索并输出生成树序列。
默认由图中最小序号结点开始,并按照结点序号升序优先。
输入: 输入第一行为结点数,第二行至最后为各边,如:1 2 表示结点1与结点2有边。
Sample Input
6
1 2
1 3
2 4
2 5
3 6
Sample Output
1 2 4 5 3 6
Hint
输出有换行。
#include <bits/stdc++.h>
#define Max_size 105
#define INTSIZE 32576
using namespace std;
// 邻接矩阵
typedef struct Arcell
{
    int adj;
} Arcell, adjMa[Max_size][Max_size];
typedef struct
{
    int vexs[Max_size];
    adjMa arcs;
    int vex, arc;
} MG;

void creatMG(MG &G)
{ // 创建不带权无向图
    int n, v1, v2;
    cin >> n;
    G.vex = n;
    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= n; j++)
        { // 初始化
            G.arcs[i][j].adj = 0;
        }
    }
    while (cin >> v1 >> v2)
    {
        G.arcs[v1][v2].adj = 1;
        G.arcs[v2][v1].adj = 1;
    }
}
int v[Max_size]; // 辅助数组
int flag = 0;
void DFS(MG G, int j)
{
    v[j] = 1; // 标记
    if (flag != 0)
        cout << " ";
    else
        flag = 1;
    cout << j;
    for (int w = 1; w <= G.vex; w++)
    {                                       // 表示从j到w有边
        if (!v[w] && G.arcs[j][w].adj != 0) // 未访问并且有边就递归
            DFS(G, w);
    }
}
void DFSTrav(MG G)
{
    for (int i = 0; i <= G.vex; i++)
    { // 辅助数组初始化
        v[i] = 0;
    }
    for (int j = 1; j <= G.vex; j++)
    {
        if (!v[j]) // 未访问就进人
            DFS(G, j);
    }
}

int main()
{
    MG G;
    adjMa p;
    creatMG(G);
    DFSTrav(G);
    cout << "\n";
    return 0;
}

无向图的环是指至少有一条边的路径,起点和终点相同。如果一个无向图没有环,那么它就是一个森林,也就是多个不相交的树的集合。 判断无向图是否有环,可以使用深度优先搜索(DFS)算法。具体做法是,从任意一个节点开始进行DFS遍历,如果在遍历的过程中遇到了已经访问过的节点,那么就说明存在环,否则就没有环。 以下是C语言实现无向图是否有环的代码: ```c #include <stdio.h> #include <stdbool.h> #define MAX_VERTEX_NUM 100 // 顶点最大个数 int visited[MAX_VERTEX_NUM]; // 记录顶点是否已经被访问 int graph[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; // 图的邻接矩阵 int vertex_num, edge_num; // 顶点个数和边个数 bool has_cycle(int v, int parent) { visited[v] = true; // 标记当前顶点已经被访问 for (int i = 0; i < vertex_num; i++) { if (graph[v][i]) { // 如果v与i之间有边 if (!visited[i]) { // 如果i顶点还没有被访问 if (has_cycle(i, v)) { // 递归访问i顶点,并且传入当前顶点v作为其父节点 return true; // 如果i顶点存在环,返回true } } else if (i != parent) { // 如果i顶点已经被访问,而且不是当前顶点v的父节点 return true; // 说明存在环,返回true } } } return false; // 没有发现环,返回false } bool is_tree() { // 初始化visited数组 for (int i = 0; i < vertex_num; i++) { visited[i] = false; } // 从第一个顶点开始进行DFS遍历 if (has_cycle(0, -1)) { // 第一个顶点没有父节点,传入-1 return false; // 存在环 } // 如果所有顶点都被访问到了,说明该图是一棵树 for (int i = 0; i < vertex_num; i++) { if (!visited[i]) { return false; } } return true; } int main() { scanf("%d %d", &vertex_num, &edge_num); // 读入图的边 for (int i = 0; i < edge_num; i++) { int u, v; scanf("%d %d", &u, &v); graph[u][v] = graph[v][u] = 1; // 无向图,所以要将两个方向都设置为1 } // 判断该图是否是一棵树 if (is_tree()) { printf("Yes\n"); } else { printf("No\n"); } return 0; } ``` 在这段代码中,`has_cycle()`函数用于判断从当前顶点v开始,是否存在环。如果存在环,则返回true,否则返回false。`is_tree()`函数则用于判断整个无向图是否是一棵树,如果是则返回true,否则返回false。最后在main函数中读入图的边,然后调用`is_tree()`函数判断该图是否是一棵树。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值