图与DFS

本文介绍了图的概念及其与二叉树的区别,重点探讨了深度优先搜索(DFS)的基本原理和应用场景。在DFS简析中,详细解释了从一个顶点开始的递归搜索过程。接着,通过DFS模板展示了如何解决求连通块的问题,特别是针对8连块的计数问题,利用DFS遍历并记录连通分量。最后,提到了树的DFS遍历,进一步扩展了DFS的应用范围。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

图与DFS

1.1简析

​ 图描述的是一些个体间的关系,与二叉树不同的是,不仅是祖先后代的层次关系,而是复杂的网状关系

1.2DFS

1.2.1DFS简析

a:从一个图的顶点点开始,对与该点有关联的点进行搜索

b:对遍历到的每个点重复a->b的操作

c:直到无点可遍历,再从没遍历过的点进行a操作。

d:所有点都遍历完毕。

简而言之,就是从一个点开始,按一条路径不断向下搜索,如果走到头,返回上一层,继续搜索未遍历到的点,以此不断循环往复直到全部遍历或者得到结果。

1.2.2DFS模板

void dfs(a1,a2,a3)
{
    if(走到尽头||找到答案)
        return ;

    if(满足搜索条件||未访问过)
        dfs(x1,x2,x3);

    return ;//回溯
}

1.2.3DFS求连通块

​ 输入一个m行n列的字符矩阵,统计字符@组成多少8连块,如果两个字符的格子相邻(上下左右对角线),就说他们同属一个8连块。求有多少8连块。<<紫书油田>>

分析:可以使用DFS遍历图,每次遍历对应一个连通分量编号用来描述格子的连通,所以每次遍历就是一个8连块。建立index二维数组,描述每个格子的连通分量,和判断是否遍历过。

代码如下:

//改自紫书代码
#include<iostream>
#include<cstring>
using namespace std;
const int maxn = 105;
char pic[maxn][maxn];
int m,n,index[maxn][maxn];

void dfs(int r, int c ,int id)
{
    if(r < 0 || r >= m || c < 0 || c >= n)  return;//越界退出
    if(index[r][c] > 0 || pic[r][c] != '@')  return;//不符合搜索条件退出
    index[r][c] = id;
    //遍历周边八个格子
    for(int i = -1; i <= 1; i++)
        for(int j = -1; j <= 1 ;j++)
            if(i != 0 || j != 0) dfs(r + i, c + j, id);
}

int main()
{
    cin>> m >>n;
    for(int i = 0;i < m ; i++)
        for(int j = 0;j < n;j++)
            cin>>pic[i][j];
    //把每个格子对应的编号置0
    memset(index,0,sizeof(index));
    int cnt = 0;
    //遍历图,每次遍历更新连通编号(即一个8连块的编号)
    //编号为0而且为@的格子能进入dfs
    for(int i = 0; i < m ;i++)
        for(int j = 0; j < n;j++)
            if(index[i][j] == 0 && pic[i][j] == '@') dfs(i,j,++cnt);
    cout<<cnt<<endl;
}

1.24树的dfs遍历

typedef struct node{
    int val;
    struct node * left;
    struct node * rigtht;
}

//前序遍历
void tree_visit(Node * root)
{
    if( root == NULL)
        return ;
    visit(root);
    tree_visit(root->left);
    tree_visit(root->right);
}

//中序遍历
void tree_visit(Node * root)
{
    if( root == NULL)
        return ;
    tree_visit(root->left);
    visit(root);
    tree_visit(root->right);
}


//后续遍历
void tree_visit(Node * root)
{
    if( root == NULL)
        return ;
    tree_visit(root->left);
    tree_visit(root->right);
    visit(root);

}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值