图-遍历(DFS+BFS)

图-遍历

    • 1.简介
    • 2.深度优先遍历dfs
    • 3.广度优先遍历bfs
    • 4.具体问题
      • 4.1 岛屿的最大面积
      • 4.2 岛屿的数量
    • 5.总结

1.简介

图是数据结构中的另一种数据结构,通常用来表示多对多的关系。在 C++ 中,图通常可以通过邻接表邻接矩阵表示。
例如:
在这里插入图片描述

2.深度优先遍历dfs

下面先给出上面图例的深度优先遍历算法代码:

#include <iostream>
#include <vector>
#include <set>

using namespace std;

// 深度优先搜索函数
void depthFirstSearch(const vector<vector<int>>& graph, int node, set<int>& visited) {
    // 输出当前节点
    cout << node << " ";
    visited.insert(node); // 标记当前节点为已访问

    // 遍历所有邻接节点
    for (int neighbor : graph[node]) {
        if (visited.find(neighbor) == visited.end()) {
            depthFirstSearch(graph, neighbor, visited);
        }
    }
}

int main() {
    // 图的邻接表表示
    vector<vector<int>> graph = {
        {3, 1},       // 0 的邻接节点
        {0, 2, 6},    // 1 的邻接节点
        {1, 8},       // 2 的邻接节点
        {0, 6, 5},    // 3 的邻接节点
        {},           // 4 没有邻接节点
        {3, 7},       // 5 的邻接节点
        {3, 1, 8},    // 6 的邻接节点
        {5, 8},       // 7 的邻接节点
        {2, 6, 7}     // 8 的邻接节点
    };

    // 记录访问的节点
    set<int> visited;

    cout << "DFS traversal starting from node 0:" << endl;
    depthFirstSearch(graph, 0, visited);

    return 0;
}

3.广度优先遍历bfs

给出广度优先遍历算法代码:

#include <iostream>
#include <vector>
#include <queue>
#include <set>

using namespace std;

// 广度优先搜索函数
void breadthFirstSearch(const vector<vector<int>>& graph, int start) {
    queue<int> q;        // 队列,用于按层次遍历节点
    set<int> visited;    // 记录已访问的节点

    // 初始化:将起始节点加入队列并标记为已访问
    q.push(start);
    visited.insert(start);

    cout << "BFS traversal starting from node " << start << ":" << endl;

    while (!q.empty()) {
        int current = q.front();
        q.pop();

        // 输出当前节点
        cout << current << " ";

        // 遍历邻接节点
        for (int neighbor : graph[current]) {
            if (visited.find(neighbor) == visited.end()) {
                q.push(neighbor);
                visited.insert(neighbor);
            }
        }
    }
    cout << endl;
}

int main() {
    // 图的邻接表表示
    vector<vector<int>> graph = {
        {3, 1},       // 0 的邻接节点
        {0, 2, 6},    // 1 的邻接节点
        {1, 8},       // 2 的邻接节点
        {0, 6, 5},    // 3 的邻接节点
        {},           // 4 没有邻接节点
        {3, 7},       // 5 的邻接节点
        {3, 1, 8},    // 6 的邻接节点
        {5, 8},       // 7 的邻接节点
        {2, 6, 7}     // 8 的邻接节点
    };

    // 从节点 0 开始广度优先遍历
    breadthFirstSearch(graph, 0);

    return 0;
}

4.具体问题

4.1 岛屿的最大面积

题目链接
在这里插入图片描述
岛屿面积计算的核心是:从某个 1 出发,找到所有相邻的 1(上下左右连接),将其视为一个连通分量,统计该连通分量的面积。DFS 可以很好地完成这一需求:一旦找到一个起始点(1),DFS 会递归地深入探索其相邻的每个方向,直到完全探索整个连通分量(即这个岛屿)。在递归返回时,可以累计面积,最终得出整个岛屿的面积。
具体代码:

class Solution {
public:
    // 深度优先搜索函数
    int dfs(vector<vector<int>>& grid, int x, int y) {
        // 检查边界条件和是否已经访问过
        if (x < 0 || x >= grid.size() || y < 0 || y >= grid[0].size() ||
            grid[x][y] == 0) {
            return 0;
        }

        grid[x][y] = 0; // 将当前格子标记为已访问
        int area = 1;   // 当前格子的面积为 1

        // 递归检查四个方向
        area += dfs(grid, x + 1, y); // 下
        area += dfs(grid, x - 1, y); // 上
        area += dfs(grid, x, y + 1); // 右
        area += dfs(grid, x, y - 1); // 左

        return area;
    }

    // 计算最大岛屿面积的函数
    int maxAreaOfIsland(vector<vector<int>>& grid) {
        int maxArea = 0;

        // 遍历整个网格
        for (int i = 0; i < grid.size(); ++i) {
            for (int j = 0; j < grid[0].size(); ++j) {
                if (grid[i][j] == 1) {
                    // 计算当前岛屿的面积
                    int area = dfs(grid, i, j);
                    // 更新最大面积
                    maxArea = max(maxArea, area);
                }
            }
        }

        return maxArea;
    }
};

4.2 岛屿的数量

题目链接
在这里插入图片描述
遍历网格中的每个格子,遇到未访问过的 1 时,将其作为一个新的岛屿,启动搜索(DFS 或 BFS)。
搜索过程中,将所有属于同一岛屿的 1 标记为访问过。使用 DFS 或 BFS,从当前 1 出发,递归或迭代访问所有相邻的 1,直到整个岛屿被处理完。每次启动搜索时,岛屿数量 count 增加 1。遍历完网格后,count 即为岛屿的总数。
给出广度优先遍历的代码:

class Solution {
public:
    void bfs(vector<vector<char>>& grid, int x, int y) {
        // 定义方向数组
        vector<pair<int, int>> directions = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
        queue<pair<int, int>> q;
        q.push({x, y});
        grid[x][y] = '0'; // 标记为已访问

        while (!q.empty()) {
            auto [cx, cy] = q.front();
            q.pop();

            // 遍历四个方向
            for (auto [dx, dy] : directions) {
                int nx = cx + dx, ny = cy + dy;
                if (nx >= 0 && nx < grid.size() && ny >= 0 &&
                    ny < grid[0].size() && grid[nx][ny] == '1') {
                    q.push({nx, ny});
                    grid[nx][ny] = '0'; // 标记为已访问
                }
            }
        }
    }

    int numIslands(vector<vector<char>>& grid) {
        int count = 0;

        for (int i = 0; i < grid.size(); ++i) {
            for (int j = 0; j < grid[0].size(); ++j) {
                if (grid[i][j] == '1') {
                    bfs(grid, i, j);
                    count++;
                }
            }
        }

        return count;
    }
};

5.总结

接下来用一个表格来对比分析一下:

特性深度优先遍历(DFS)广度优先遍历(BFS)
实现方式使用递归或显式栈使用队列
遍历顺序尽可能沿一个分支深入按层次逐步扩展
应用场景适合路径搜索、连通性判断适合最短路径、分层搜索
时间复杂度O(V+E)O(V+E)
空间复杂度O(V)(递归栈)O(V)(队列)

总结:DFS 更适合问题规模较小或需要深入搜索的场景(如路径搜索、连通分量)。BFS 更适合寻找最短路径或分层问题。根据问题特性我们选择合适的遍历方式,可以提高算法效率和代码清晰度。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/936470.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

python中向量指的是什么意思

一、向量是什么 在数学中&#xff0c;向量&#xff08;也称为欧几里得向量、几何向量、矢量&#xff09;&#xff0c;指具有大小&#xff08;magnitude&#xff09;和方向的量。它可以形象化地表示为带箭头的线段。箭头所指&#xff1a;代表向量的方向&#xff1b;线段长度&am…

Vulhub:Log4j[漏洞复现]

CVE-2017-5645(Log4j反序列化) 启动靶场环境 docker-compose up -d 靶机IPV4地址 ifconfig | grep eth0 -A 5 ┌──(root㉿kali)-[/home/kali/Desktop/temp] └─# ifconfig | grep eth0 -A 5 eth0: flags4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 in…

[OpenGL] Transform feedback 介绍以及使用示例

一、简介 本文介绍了 OpenGL 中 Transform Feedback 方法的基本概念和代码示例。 二、Transform Feedback 介绍 1. Transform Feedback 简介 根据 OpenGL-wiki&#xff0c;Transform Feedback 是捕获由顶点处理步骤&#xff08;vertex shader 和 geometry shader&#xff0…

探秘 AI Agent 之 Coze 智能体:从简介到搭建全攻略(4/30)

一、Coze 智能体概述 &#xff08;一&#xff09;Coze 智能体是什么 Coze 智能体是基于机器学习和自然语言处理技术的软件实体&#xff0c;它在人工智能领域扮演着重要的角色&#xff0c;能够像一个智能助手一样&#xff0c;通过与外界环境进行交互学习&#xff0c;进而执行各…

游戏引擎学习第47天

仓库: https://gitee.com/mrxiao_com/2d_game 昨天我们花了一点时间来修复一个问题&#xff0c;但基本上是在修复这个问题的过程中&#xff0c;我们决定添加一个功能&#xff0c;那就是在屏幕上控制多个实体。所以如果我有一个手柄&#xff0c;我可以添加另一个角色&#xff0…

CAPL如何设置或修改CANoe TCP/IP协议栈的底层配置

在CANoe中创建网络节点作为以太网主机时,可以给其配置独立的TCP/IP Stack。 配置的协议栈有一些底层配置参数可以在界面上设置或修改,比如: MTU上图中MTU显示500只是图形界面显示错误,正确值是1500。 TCP延迟确认这些参数也可以通过CAPL动态配置,甚至CAPL还可以配置很多界…

RabbitMQ实现消息发送接收——实战篇(路由模式)

本篇博文将带领大家一起学习rabbitMQ如何进行消息发送接收&#xff0c;我也是在写项目的时候边学边写&#xff0c;有不足的地方希望在评论区留下你的建议&#xff0c;我们一起讨论学习呀~ 需求背景 先说一下我的项目需求背景&#xff0c;社区之间可以进行物资借用&#xff0c…

计算机进制的介绍

一.进制介绍 对于整数&#xff0c;有四种表示方式: 1&#xff09;二进制:0,1&#xff0c;满2进1。 在golang中&#xff0c;不能直接使用二进制来表示一个整数&#xff0c;它沿用了c的特点。 参考:Go语言标准库文档中文版 | Go语言中文网 | Golang中文社区 | Golang中国 //赋值…

基于卷积神经网络的Caser算法

将一段交互序列嵌入到一个以时间为纵轴的平面空间中形成“一张图”后&#xff0c;基于卷积序列嵌入的推荐&#xff08;Caser&#xff09;算法利用多个不同大小的卷积滤波器&#xff0c;来捕捉序列中物品间的点级&#xff08;point-level&#xff09;、联合的&#xff08;union-…

基于STM32设计的粮食仓库(粮仓)环境监测系统

一、前言 当前项目使用的相关软件工具、传感器源代码工程已经上传到网盘&#xff08;实时更新项目内容&#xff09;&#xff1a;https://ccnr8sukk85n.feishu.cn/wiki/QjY8weDYHibqRYkFP2qcA9aGnvb?fromfrom_copylink 1.1 项目开发背景 随着现代农业的发展和粮食储存规模的…

计算机网络-传输层 TCP协议(上)

目录 报头结构 TCP的可靠传输机制 核心机制一&#xff1a;确认应答 TCP的序号和确认序号 核心机制二&#xff1a;丢包重传 核心机制三&#xff1a;连接管理 建立连接-三次握手 断开连接-四次挥手 核心机制四&#xff1a;滑动窗口 数据包已经抵达, ACK被丢了 数据包就…

【经验分享】容器云运维的知识点

最近忙于备考没关注&#xff0c;有次点进某小黄鱼发现首页出现了我的笔记还被人收费了 虽然我也卖了一些资源&#xff0c;但我以交流、交换为主&#xff0c;笔记都是免费给别人看的 由于当时刚刚接触写的并不成熟&#xff0c;为了避免更多人花没必要的钱&#xff0c;所以决定公…

纯血鸿蒙崛起,原生Android挑战?两大操作系统巅峰对决,智能设备未来谁主沉浮?

鸿蒙HarmonyOS和原生Android系统虽然在一些方面相似&#xff0c;但在架构、设计理念、API、开发工具等方面存在一些差异。鸿蒙系统的目标是跨设备、分布式的操作系统&#xff0c;强调多设备协同和资源共享&#xff0c;而Android则主要集中在智能手机和移动设备领域。 下面将从…

新手快速入门!低功耗4G模组Air780E——使用文件系统存储温湿度数据来啦~

小伙伴们&#xff0c;今天我们来学习低功耗4G模组Air780E快速入门之使用文件系统存储温湿度数据。一起接着看下去吧&#xff01; 一、编写脚本 1.1 准备资料 780E开发板 780E开发板设计资料 LuatOS-Air780E-文件系统的使用-程序源码demo TCP/UDP测试服务器 API使用介绍 …

vscode中插件ofExtensions的debug模式也无法查看U、p等openfoam中foam类型的变量

插件介绍&#xff1a; 主要内容如下&#xff1a; 以自编译的$HOME/OpenFOAM-7例&#xff0c;如果OFdebugopt设置为WM_COMPILE_OPTIONDebug&#xff0c;那最终的激活环境的命令为source $HOME/OpenFOAM/OpenFOAM-8/etc/bashrc WM_COMPILE_OPTIONDebug&#xff0c;这时候$FOAM_…

【收藏】Cesium 限制相机倾斜角(pitch)滑动范围

1.效果 2.思路 在项目开发的时候&#xff0c;有一个需求是限制相机倾斜角&#xff0c;也就是鼠标中键调整视图俯角时&#xff0c;不能过大&#xff0c;一般 pitch 角度范围在 0 至 -90之间&#xff0c;-90刚好为正俯视。 在网上查阅了很多资料&#xff0c;发现并没有一个合适的…

【经验分享】私有云运维的知识点

最近忙于备考没关注&#xff0c;有次点进某小黄鱼发现首页出现了我的笔记还被人收费了 虽然我也卖了一些资源&#xff0c;但我以交流、交换为主&#xff0c;笔记都是免费给别人看的 由于当时刚刚接触写的并不成熟&#xff0c;为了避免更多人花没必要的钱&#xff0c;所以决定公…

Please activate LaTeX Workshop sidebar item to render the thumbnail of a PDF

Latex代码中使用pdf图片&#xff0c;无法预览&#xff0c;提示&#xff1a; Please activate LaTeX Workshop sidebar item to render the thumbnail of a PDF 解决办法&#xff1a; 点击左边这个刷新下即可

QT:Widgets中的事件

事件的处理 (1)重新实现部件的paintEvent()、mousePressEvent()等事件处理函数。这是最常用的一种方法&#xff0c;不过它只能用来处理特定部件的特定事件。 (2)重新实现notify()函数。这个函数功能强大&#xff0c;提供了完全的控制&#xff0c;可以在事件过滤器得到事件之前…

Windows如何安装go环境,离线安装beego

一、安装go 1、下载go All releases - The Go Programming Language 通过网盘分享的文件&#xff1a;分享的文件 链接: https://pan.baidu.com/s/1MCbo3k3otSoVdmIR4mpPiQ 提取码: hxgf 下载amd64.zip文件&#xff0c;然后解压到指定的路径 2、配置环境变量 需要新建两个环境…