c++ 深度和广度优先搜索

深度优先搜索 (DFS)

DFS 是一种递归的遍历方法,它从根节点开始,沿着树的每一条路径深度遍历,直到到达叶子节点,之后回溯到上一个节点继续遍历。

主要特点:

  • 深度优先搜索:从根节点开始,一直向下搜索直到叶子节点,然后回溯。
  • 适合递归实现,栈可以用来模拟递归过程。
  • 在树或图中,DFS的复杂度通常为 O(V + E),其中V是节点数,E是边数。
#include <iostream>
#include <vector>using namespace std;// 定义二叉树节点
struct TreeNode {int val;TreeNode* left;TreeNode* right;TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
};// 递归实现深度优先遍历(前序遍历)
void dfs(TreeNode* root) {if (!root) {return;  // 递归结束条件}// 访问当前节点cout << root->val << " ";// 递归访问左子树dfs(root->left);// 递归访问右子树dfs(root->right);
}int main() {// 构建一个简单的二叉树TreeNode* root = new TreeNode(1);root->left = new TreeNode(2);root->right = new TreeNode(3);root->left->left = new TreeNode(4);root->left->right = new TreeNode(5);// 执行深度优先遍历(前序遍历)cout << "DFS Preorder Traversal: ";dfs(root);cout << endl;return 0;
}

图的连通分量

DFS可以用来在无向图中查找连通分量。一个连通分量是图中一个子集,其中每一对节点都通过边相互连接。DFS可以遍历每个连通分量,从一个未访问的节点开始遍历并标记所有可以访问的节点,直到整个连通分量都被遍历到。

示例:计算图中的连通分量

#include <iostream>
#include <vector>using namespace std;class Graph {
public:int V;  // 图的节点数vector<vector<int>> adj;  // 邻接表表示的图Graph(int V) {this->V = V;adj.resize(V);}void addEdge(int u, int v) {adj[u].push_back(v);adj[v].push_back(u);  // 无向图}void dfs(int v, vector<bool>& visited) {visited[v] = true;cout << v << " ";  // 访问当前节点// 遍历所有邻居for (int neighbor : adj[v]) {if (!visited[neighbor]) {dfs(neighbor, visited);}}}int countConnectedComponents() {vector<bool> visited(V, false);int count = 0;// 对每一个未访问过的节点执行DFSfor (int i = 0; i < V; ++i) {if (!visited[i]) {cout << "Connected component " << ++count << ": ";dfs(i, visited);cout << endl;}}return count;}
};int main() {Graph g(6);  // 创建一个有6个节点的图// 添加边g.addEdge(0, 1);g.addEdge(0, 2);g.addEdge(3, 4);g.addEdge(5, 5);  // 自环,表示一个单独的连通分量cout << "Number of connected components: " << g.countConnectedComponents() << endl;return 0;
}

广度优先搜索 (BFS)

BFS 是一种逐层遍历的算法,从根节点开始,先访问根节点的所有邻居节点,再依次访问其邻居的邻居,直到所有节点都被访问。

主要特点:

  • 广度优先搜索:从根节点开始,逐层访问所有节点。
  • BFS 使用队列来存储当前层的节点,先进先出 (FIFO) 的队列实现了逐层遍历。
  • 在树或图中,BFS的复杂度通常为 O(V + E),其中V是节点数,E是边数。
#include <iostream>
#include <queue>
#include <vector>using namespace std;// 定义二叉树节点
struct TreeNode {int val;TreeNode* left;TreeNode* right;TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
};// 广度优先遍历(层序遍历)
vector<vector<int>> bfs(TreeNode* root) {vector<vector<int>> result;  // 存储每一层的节点if (!root) {return result;}queue<TreeNode*> q;  // 队列q.push(root);while (!q.empty()) {int levelSize = q.size();  // 当前层的节点数vector<int> currentLevel;  // 存储当前层的节点值for (int i = 0; i < levelSize; ++i) {TreeNode* node = q.front();q.pop();currentLevel.push_back(node->val);// 将左右子节点加入队列if (node->left) {q.push(node->left);}if (node->right) {q.push(node->right);}}result.push_back(currentLevel);  // 当前层遍历完毕}return result;
}int main() {// 构建一个简单的二叉树TreeNode* root = new TreeNode(1);root->left = new TreeNode(2);root->right = new TreeNode(3);root->left->left = new TreeNode(4);root->left->right = new TreeNode(5);// 执行广度优先遍历(层序遍历)vector<vector<int>> result = bfs(root);cout << "BFS Level Order Traversal: \n";for (const auto& level : result) {for (int val : level) {cout << val << " ";}cout << endl;}return 0;
}

最短路径问题

BFS非常适合解决无权图中的最短路径问题,即在图中寻找从起点到终点的最短路径。由于BFS是逐层扩展的,它可以保证第一次到达某个节点时就是从起点到该节点的最短路径。

示例:无权图中从源节点到目标节点的最短路径

#include <iostream>
#include <vector>
#include <queue>using namespace std;class Graph {
public:int V;  // 节点数量vector<vector<int>> adj;  // 邻接表表示的图Graph(int V) {this->V = V;adj.resize(V);}void addEdge(int u, int v) {adj[u].push_back(v);adj[v].push_back(u);  // 无向图}// 广度优先搜索,计算从source到其他节点的最短路径vector<int> bfsShortestPath(int source) {vector<int> dist(V, -1);  // dist[i]表示从source到节点i的距离queue<int> q;// 初始化dist[source] = 0;q.push(source);while (!q.empty()) {int node = q.front();q.pop();// 遍历所有邻居for (int neighbor : adj[node]) {if (dist[neighbor] == -1) {  // 如果该邻居未被访问dist[neighbor] = dist[node] + 1;q.push(neighbor);}}}return dist;}
};int main() {Graph g(6);// 添加边g.addEdge(0, 1);g.addEdge(0, 2);g.addEdge(1, 3);g.addEdge(1, 4);g.addEdge(2, 5);vector<int> dist = g.bfsShortestPath(0);  // 从节点0开始BFScout << "Shortest path distances from node 0: ";for (int i = 0; i < dist.size(); ++i) {cout << dist[i] << " ";}cout << endl;return 0;
}

拓扑排序

拓扑排序是有向无环图(DAG)中的一种排序方式,它将图中的所有节点排列成一个线性序列,且每条边 (u, v) 都满足 uv 前面。拓扑排序有多个应用,例如任务调度、编译依赖等。

拓扑排序的应用通常使用 BFS(结合入度)来实现。

示例:拓扑排序(使用BFS)

#include <iostream>
#include <vector>
#include <queue>using namespace std;class Graph {
public:int V;  // 节点数vector<vector<int>> adj;  // 邻接表vector<int> inDegree;  // 每个节点的入度Graph(int V) {this->V = V;adj.resize(V);inDegree.resize(V, 0);}void addEdge(int u, int v) {adj[u].push_back(v);inDegree[v]++;  // 目标节点v的入度增加}vector<int> topologicalSort() {queue<int> q;vector<int> result;// 将所有入度为0的节点入队for (int i = 0; i < V; ++i) {if (inDegree[i] == 0) {q.push(i);}}while (!q.empty()) {int node = q.front();q.pop();result.push_back(node);// 遍历所有邻接节点,减少其入度for (int neighbor : adj[node]) {if (--inDegree[neighbor] == 0) {q.push(neighbor);}}}return result;}
};int main() {Graph g(6);// 添加有向边g.addEdge(5, 2);g.addEdge(5, 0);g.addEdge(4, 0);g.addEdge(4, 1);g.addEdge(2, 3);g.addEdge(3, 1);vector<int> result = g.topologicalSort();cout << "Topological Sort: ";for (int node : result) {cout << node << " ";}cout << endl;return 0;
}

总结

  • 深度优先搜索 (DFS):采用递归(或栈)策略,从根节点出发,一直深入到叶子节点。适合在树结构中需要访问每个节点的场景,如路径查找、图的遍历等。
    • 典型实现:前序、中序、后序遍历。
  • 广度优先搜索 (BFS):采用队列策略,从根节点开始,逐层访问节点。适合查找最短路径等场景,尤其在图算法中广泛应用。
    • 典型实现:层序遍历。

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

0成本添加访问级监控

互联网的安全感这个概念源于阿里。顾名思义&#xff0c;让互联网的用户对于web产品能够产生足够的信任和依赖。特别是涉及到用户资金交易的站点&#xff0c;一次严重的用户资料泄露就可以彻底毁掉你的品牌。 然而当前阶段除了bat大部分互联网行业的企业对于网络安全给的重视都…

分布式系统稳定性建设-性能优化篇

分布式系统稳定性建设-性能优化篇 系统稳定性建设是系统工程的核心内容之一。以下是一些重要的方面: 架构设计: 采用模块化、松耦合的架构设计,以提高系统的可扩展性和可维护性。合理划分系统功能模块,降低单个模块的复杂度。定义清晰的接口和数据交换标准,确保各模块之间协调…

Web端高效BIM 3D可视化引擎HOOPS Communicator技术解析!

HOOPS Communicator是一款简单而强大的工业级高性能3D Web可视化开发包&#xff0c;专注于Web端工程图形渲染。采用了先进的流式加载方式&#xff0c;并支持服务端和客户端渲染&#xff0c;是可以在云端进行部署和无缝集成的新技术平台。 灵活且易于部署&#xff0c;可在以工程…

C/C++实现tcp客户端和服务端的实现(从零开始写自己的高性能服务器)

目录 tcp客户端通信流程 tcp客户端设计 1、创建通信对象 2、链接服务器 3、发送数据 / 读取数据 4、关闭通信 tcp服务端设计 1、创建通信对象 2、绑定服务器地址信息 3、设置服务器为监听模式 4、接收客户的链接请求 编写tcp客户端和服务端&#xff0c;实现双向通信…

C++ 容器全面剖析:掌握 STL 的奥秘,从入门到高效编程

引言 C 标准模板库&#xff08;STL&#xff09;提供了一组功能强大的容器类&#xff0c;用于存储和操作数据集合。不同的容器具有独特的特性和应用场景&#xff0c;因此选择合适的容器对于程序的性能和代码的可读性至关重要。对于刚接触 C 的开发者来说&#xff0c;了解这些容…

快速上手并使用Muduo库

Muduo muduo库是基于主从reactor模型的高性能服务器&#xff08;高并发服务器&#xff09;框架 reactor模型&#xff1a;基于事件触发的模型&#xff08;基于epoll进行IP事件监控&#xff09; 主从reactor模型&#xff1a;将IO事件监控有进行进一步的层次划分 主reactor&#x…

深入解析【C++多态】:探索面向对象编程中的动态绑定与行为多样性和多态的核心概念与应用实践

&#x1f31f;个人主页&#xff1a;落叶 &#x1f31f;当前专栏: C专栏 目录 多态的概念 多态的定义及实现 实现多态还有两个必须重要条件 虚函数 虚函数的重写/覆盖 多态场景的⼀个选择题 虚函数重写的⼀些其他问题 协变(了解进行) 析构函数的重写 override 和 final关…

React Native Mac 环境搭建

下载 Mac 版Android Studio 下载 安装 JDK 环境 Flutter 项目实战-环境变量配置一 安装 Node.js 方式一 通过Node.js 官网下载 下载完成后点击安装包进行安装 安装完成

【Word】一键批量引用论文上标——将正文字体改为上标格式

【Word】一键批量引用论文上标——将正文字体改为上标格式 写在最前面Word一键批量引用论文上标技巧分享核心思路&#xff1a;Word 替换功能 通配符步骤详解1. 打开 Word 替换功能2. 输入通配符模式3. 设置替换格式为上标4. 批量替换 实际效果展示技巧扩展 &#x1f308;你好呀…

深入探索Python数据可视化:自定义颜色映射、标签与进阶技巧

目录 一、自定义颜色映射&#xff08;Cmap&#xff09; 1. 内置Cmap类型 2. 使用内置Cmap 3. 自定义Cmap 二、标签添加 1. 在散点图上添加标签 2. 在折线图上标记关键点 3. 在柱状图上添加标签 三、进阶技巧 1. 多图形布局 2. 添加图例 3. 3D数据可视化 四、总结 …

【Java SE】数据库连接池

数据库连接池是一个管理数据库连接的容器。它的主要作用是分配和管理数据库连接&#xff0c;允许应用程序重复使用现有的连接&#xff0c;而不是每次都重新建立新的连接。此外&#xff0c;连接池会释放那些空闲时间超过最大限制的连接&#xff0c;从而避免因未及时释放连接而造…

FastAPI重载不生效?解决PyCharm中Uvicorn无法重载/重载缓慢的终极方法!

文章目录 📖 介绍 📖🏡 演示环境 🏡📒 重载缓慢 📒📝 问题概述🚨 相关原因📝 解决方案一📝 解决方案二📝 解决方案三📝 解决方案四⚓️ 相关链接 ⚓️📖 介绍 📖 在使用FastAPI开发时,reload=True 本应让你在修改代码后自动重启服务,提升开发效率…

CPU算法分析LiteAIServer视频智能分析平台未戴安全帽检测算法

随着人工智能技术的不断进步&#xff0c;CPU算法分析在视频智能分析平台中的应用日益广泛。特别是在工地安全管理领域&#xff0c;未戴安全帽检测算法已成为一项关键的安全保障措施。LiteAIServer视频智能分析平台通过结合CPU的高效运算能力和先进的深度学习算法&#xff0c;实…

两网站定时数据exchange项目详解

功能说明 A网站&#xff1a;用户可以通过表单输入嫌疑人信息&#xff0c;这些信息会被存储在内存中&#xff0c;并通过API接口返回。B网站&#xff1a;通过API接口接收从A网站同步过来的嫌疑人数据&#xff0c;并显示这些数据。主应用&#xff1a;使用APScheduler每隔1分钟从A…

【云计算】腾讯云架构高级工程师认证TCP--考纲例题,知识点总结

【云计算】腾讯云架构高级工程师认证TCCP–知识点总结&#xff0c;排版整理 文章目录 1、云计算架构概论1.1 五大版块知识点&#xff08;架构设计&#xff0c;基础服务&#xff0c;高阶技术&#xff0c;安全&#xff0c;上云&#xff09;1.2 课程详细目录1.3 云基础架构设计1.4…

sql server查看当前正在执行的sql

#统计某类sql执行次数&#xff0c;并按总体cpu消耗时间降序排序 with a as ( select er.session_id,db_name(er.database_id) as DBNAME,sy.last_batch AS 最后执行时间, er.cpu_time ,er.total_elapsed_time/1000 as sum_elapsed_time_s, CAST(csql.text AS varchar(8000)) A…

【UE5】Slider控件样式

实现根据滑柄位置确定滑条样式的功能&#xff0c;效果如下。 效果 步骤 1. 添加Slider控件和文本控件&#xff0c;其中文本控件用于显示滑条的值 2. 文本控件绑定变量&#xff0c;这里变量为“Year” 3. 当滑条的值变更后&#xff0c;设置“Year”的值&#xff0c;然后调用函…

JVM性能分析工具JProfiler的使用

一、基本概念 JProfiler&#xff1a;即“Java Profiler”&#xff0c;即“Java分析器”或“Java性能分析工具”。它是一款用于Java应用程序的性能分析和调试工具&#xff0c;主要帮助开发人员识别和解决性能瓶颈问题。 JVM&#xff1a;即“Java Virtual Machine”&#xff0c…

TongRDS 可视化连接

说明&#xff1a;TongRDS 增加了 redis 兼容接口&#xff0c;所以 redis 能连接的可视化方式&#xff0c;TongRDS 也是可以的 Redis Insight Redis Insight DataGrip DataGrip

【WPF】Prism学习(八)

Prism Dependency Injection 1.处理解析错误 1.1. 处理解析错误&#xff1a; 这个特性是在Prism 8中引入的&#xff0c;如果你的应用目标是早期版本&#xff0c;则不适用。 1.2. 异常发生的原因&#xff1a; 开发者可能会遇到多种原因导致的异常&#xff0c;常见的错误包括…