c# 广度优先搜索(Breadth-First Search,BFS)

news2025/2/25 15:44:44

        在这篇文章中我将讨论用于树和图的两种遍历机制之一。将使用 C# 示例介绍广度优先搜索 (BFS)。图是最具挑战性和最复杂的数据结构之一。

        广度优先搜索的工作原理:广度优先搜索 (BFS)是一种探索树或图的方法。在 BFS 中,您首先探索一步之外的所有节点,然后探索两步之外的所有节点,依此类推。

        如果我们熟悉广度优先搜索,那么理解系统设计概念和破解面试问题就会很容易。

        广度优先搜索就像向池塘中心扔一块石头。您探索的节点从起点“产生涟漪”。

以下是 BFS 从根开始遍历这棵树的方式:

广度优先优先遍历树
        在上图的第一张图中,我们从最顶层的节点开始。

        在第二张图中,我们遍历第二层存在的所有节点。在第三张图像中,所有节点都出现在第三层,依此类推。直到我们到达终点。

优点:

BFS 将找到  起点和任何其他可到达节点之间的最短路径。深度优先搜索不一定能找到最短路径。
缺点:

二叉树上的 BFS 通常 比 DFS 需要更多的内存。

示例一:

广度优先搜索代码示例
在下面的代码中,我尝试创建与下图所示相同的结构。

static void Main(string[] args)
        {
             IDictionary> tree = new Dictionary>();
            tree[1] = new List { 2, 3, 4 };
            tree[2] = new List { 5 };
            tree[3] = new List { 6, 7 };
            tree[4] = new List { 8 };
            tree[5] = new List { 9 };
            tree[6] = new List { 10 };
            HashSet itemCovered = new HashSet();
            Queue queue = new Queue();
            queue.Enqueue(tree.ElementAt(0).Key);
            while (queue.Count > 0)
            {
                var element = queue.Dequeue();
                if (itemCovered.Contains(Convert.ToInt32(element)))
                    continue;
                else
                    itemCovered.Add(Convert.ToInt32(element));
                Console.WriteLine(element);
                List neighbours;
                tree.TryGetValue(Convert.ToInt32(element), out neighbours);
                if (neighbours == null)
                    continue;
                foreach (var item1 in neighbours)
                {
                    queue.Enqueue(item1);
                }
            }
        }
}

我正在上面的代码中执行以下步骤来遍历树:

首先水平移动,访问当前层的所有节点
移动到下一层
我正在使用队列来推送正在遍历的项目,并将该项目的所有邻居添加到队列中。一旦遍历将它们弹出。

上述代码的输出如下图所示:

广度优先搜索问题:
给定 root 二叉树的 ,返回  树 中每一行中最大值的数组(从 0 开始索引)。 

解决方案:
作为解决方案的一部分,我们将遍历一级的所有节点并尝试找到最大节点。
1、将根节点添加到队列中。
2、遍历队列,直到队列为空。
3、获取队列中元素的数量。
4、遍历元素直到计数为止。
5、获取内循环中的最大值。

public int[] FindLargestValueinEachTreeRowMethod(TreeNode root)
        {
            List<int> result = new List<int>();
            if (root == null) return result.ToArray();

            Queue dfs_queue = new Queue();
            dfs_queue.Enqueue(root);

            while (dfs_queue.Count > 0)
            {
                int max_value = Int32.MinValue;
                int elements_count = dfs_queue.Count;

                for (int i = 0; i <= elements_count; i++)
                {
                    TreeNode node = dfs_queue.Dequeue();
                    max_value = Math.Max((int)max_value, (int)node.val);
                    if (node.left != null) dfs_queue.Enqueue(node.left);
                    if (node.right != null) dfs_queue.Enqueue(node.right);
                }

                result.Add(max_value);
            }

            return result.ToArray();
            
        }

广度优先搜索的实际应用:
我被问到一个与 BFS 相关的非常有用且有趣的编程面试问题。下面是问题。

给你一张地铁站的网格图,编写一个函数来输出从每个路口到最近车站的距离。从一个点到另一个点时,你不能沿对角线移动。答案有点复杂,但也不是很难。

输入:

。。。。。X
。。。。。。
。。。。。。
。X 。。。。
。。。。X 。

输出:

4 3 3 2 1 0 3
2 3 3
2 1 2 1 2 3 2
2 1 0 1 2 1 2
2 1 2 1 0 1

示例二:

图是数据结构和算法中非常重要的话题

class BfsGraph
   {
       LinkedList<int>[] _adj;
       int _V;

       public BfsGraph(int v)
       {
           _adj = new LinkedList<int>[v];

           for (int i = 0; i < v; i++)
           {
               _adj[i] = new LinkedList<int>();
           }
           _V = v;

       }

       public void AddEdge(int v, int w)
       {
           _adj[v].AddLast(w);
       }

       public void BFS(int v)
       {

           Queue<int> q = new Queue<int>();
           bool[] flag = new bool[_V];


           q.Enqueue(v);
           flag[v] = true;
           Console.WriteLine(v);

           while (q.Count > 0)
           {
               int w = q.Dequeue();
               LinkedList<int> linledList = _adj[w];
               LinkedListNode<int> currentNode = linledList.First;
               while (currentNode != null && !flag[currentNode.Value])
               {
                   Console.WriteLine(currentNode.Value);
                   q.Enqueue(currentNode.Value);
                   flag[currentNode.Value] = true;
                   currentNode = currentNode.Next;
               }
           }


       }


   }

        上面的 C# 代码定义了一个名为 BfsGraph 的类,它表示图数据结构并实现广度优先搜索 (BFS) 算法。该类有两个实例变量:_adj(表示图的邻接列表的 LinkedList<int> 对象数组)和 _V(表示图中顶点数的 int)。

        BfsGraph 构造函数采用 int 参数 v 表示图中的顶点数。它使用大小为 v 的 LinkedList<int> 对象的新数组初始化 _adj 数组,并将 _V 的值设置为 v。构造函数还使用新的 LinkedList<int> 对象初始化 _adj 数组的每个元素。

        AddEdge 方法采用两个 int 参数 v 和 w,表示图中的两个顶点。它通过将 w 添加到链表末尾 _adj 数组中索引 v 处来在这两个顶点之间添加一条边。

        BFS 方法采用一个 int 参数 v 表示 BFS 遍历的起始顶点。它创建一个新的 Queue<int> 对象来存储要访问的顶点,并创建一个新的 bool[] 数组来跟踪已访问的顶点。该方法将起始顶点 v 排入队列,将标志数组中的相应元素设置为 true,并使用 Console.WriteLine 输出其值。

        然后该方法进入一个循环,一直持续到队列为空为止。在每次迭代中,它都会从队列中出列一个顶点,从 _adj 数组中检索其邻接列表,并使用 while 循环迭代其元素。对于邻接列表中的每个未访问的顶点,它使用 Console.WriteLine 输出其值,将其排队并将其在标志数组中的相应元素设置为 true。

下面的示例演示了如何使用此类创建具有 4 个顶点的图,并从顶点 2 开始执行 BFS 遍历:

var graph = new BfsGraph(4);
graph.AddEdge(0, 1);
graph.AddEdge(0, 2);
graph.AddEdge(1, 2);
graph.AddEdge(2, 0);
graph.AddEdge(2, 3);
graph.AddEdge(3, 3);

Console.WriteLine("Breadth First Traversal starting from vertex 2:");
graph.BFS(2);

此代码创建具有 4 个顶点的 BfsGraph 类的新实例,使用 AddEdge 方法在它们之间添加边,并使用 BFS 方法从顶点 2 开始执行 BFS 遍历。该代码的输出将是:

从顶点开始广度优先遍历 2:
2
0
3

时间复杂度:O(v+e),其中 v 是节点数,e 是边数。

辅助空间:O(v)

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

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

相关文章

Mac 重新安装系统

Mac 重新安装系统 使用可引导安装器重新安装&#xff08;可用于安装非最新的 Mac OS&#xff0c;系统降级&#xff0c;需要清除所有数据&#xff09; 插入制作好的可引导安装器&#xff08;U盘或者移动固态硬盘&#xff09;&#xff0c;如何制作可引导安装器将 Mac 关机将 Ma…

【多智能体】MetaGPT配置教程(应用智谱AI的GLM-4)

MetaGPT配置教程&#xff08;使用智谱AI的GLM-4&#xff09; 文章目录 MetaGPT配置教程&#xff08;使用智谱AI的GLM-4&#xff09;零、为什么要学MetaGPT一、配置环境二、克隆代码仓库三、设置智谱AI配置四、 示例demo&#xff08;狼羊对决&#xff09;五、参考链接 零、为什么…

Appium手机Android自动化

目录 介绍 什么是APPium&#xff1f; APPium的特点 环境准备 adb(android调试桥)常用命令 appium图形化简单使用 连接手机模拟器 使用appium桌面端应用程序 ​编辑 整合java代码测试 环境准备 引入所需依赖 书写代码简单启动 ​编辑 Appium元素定位 id定位 介…

unity自定义着色器基础

这些内置渲染管线的着色器示例演示了编写自定义着色器的基础知识&#xff0c;并涵盖了常见的用例。 有关编写着色器的信息&#xff0c;请参阅编写着色器。 设置场景 第一步是创建一些用于测试着色器的对象。在主菜单中选择 Game Object > 3D Object > Capsule。然后&a…

AMEYA360:广和通5G智能模组SC171支持Android、Linux和Windows系统,拓宽智能物联网应用

世界移动通信大会2024期间&#xff0c;广和通宣布&#xff1a;5G智能模组SC171除支持Android操作系统外&#xff0c;还兼容Linux和Windows系统&#xff0c;帮助更多智能终端客户快速迭代产品&#xff0c;拓宽智能化应用覆盖范围。 广和通SC171系列基于高通QCM6490物联网解决方案…

2022年下半年教师资格证考试《综合素质》(中学)题

1.一位肖老师认为&#xff1a;“教师在教学中不能只关注学科层面的知识&#xff0c;还要爱学生&#xff0c;建立和谐的师生关系”。她在日常工作中以此为行动指南&#xff0c;这表明肖老师所处的教师专业发展阶段是&#xff08; B&#xff09;。 A“虚拟关注”阶段 B“自我更新…

ubuntu22.04工具整理以及安装使用方式

截图工具 火焰截图 安装&#xff1a; sudo apt install flameshot增加自定义快捷键&#xff1a; 然后就可是使用是指的快捷键进行截图了。 如果没有在截图上编辑的需要&#xff0c;其实自带的截图也够用的。

这可能是你少有的能get到测试用例编写精髓的机会!

自动化测试用例的编写是实现项目自动化的核心&#xff0c;合理的用例设计是保证自动化效益和实用性的关键&#xff0c;也直接决定了自动化脚本是否具备可扩展和可维护性。由此&#xff0c;本篇文章主要为大家介绍了测试用例编写的规范和注意事项。 一、自动化测试用例选择 自…

如何在宝塔面板中设置FTP文件传输服务并实现远程文件管理

文章目录 1. Linux安装Cpolar2. 创建FTP公网地址3. 宝塔FTP服务设置4. FTP服务远程连接小结 5. 固定FTP公网地址6. 固定FTP地址连接 宝塔FTP是宝塔面板中的一项功能&#xff0c;用于设置和管理FTP服务。通过宝塔FTP&#xff0c;用户可以创建FTP账号&#xff0c;配置FTP用户权限…

APRISO的低代码能力降低MOM系统全生命周期成本

前言 进入21世纪以来企业之间的竞争发生了巨大的变化&#xff0c;特别是近10年来&#xff0c;客户对产品的需求逐渐多样化&#xff0c;制造企业的生产模式也开始由大批量的刚性生产变为了多品种、小批量的柔性生产模式&#xff0c;生产线也从以前的手工方式转为了以自动化的机…

【软考高项】【计算专题】- 6 - 成本类 - 挣值管理

目录 一、知识点 1、基础概念 1.1 教材定义 1.2 理解方式 方式一&#xff1a;使用公式理解 方式二&#xff1a;使用语言描述 2、总结 2.1 三个参数 2.2 四个指标 2.3 其他关键参数 二、真题举例 高级2014年下半年案例分析试题 【问题1】 【问题2】 【问题3】 一…

将任何网页变成桌面应用,全平台支持 | 开源日报 No.184

tw93/Pake Stars: 20.9k License: MIT Pake 是利用 Rust 轻松构建轻量级多端桌面应用的工具。 与 Electron 包大小相比几乎小了 20 倍&#xff08;约 5M&#xff01;&#xff09;使用 Rust Tauri&#xff0c;Pake 比基于 JS 的框架更轻量和更快内置功能包括快捷方式传递、沉浸…

【Python 数据分析 实战案例】通过用户和订单的数据分析,制定营销策略

在互联网行业中&#xff0c;电子商务领域绝对是数据分析用途最多的地方&#xff0c;各大电商平台都依赖数据分析帮助其挖掘用户订单增长机会。比如某宝的随手买一件&#xff0c;核心思路也就是根据用户的日常浏览内容及停留时间&#xff0c;以及订单的关联度来进行推荐的。 本…

秒杀小程序怎么做_尽享指尖上的超值优惠!

秒杀小程序&#xff1a;掀起购物狂潮&#xff0c;尽享指尖上的超值优惠&#xff01; 在当下数字化、信息化的社会里&#xff0c;购物方式也在不断地变革和升级。其中&#xff0c;秒杀小程序以其独特的魅力和便捷性&#xff0c;逐渐成为了众多消费者热衷的购物渠道。那么&#…

1854034-70-0,Bis-Sulfone-PEG4-DBCO,能够与蛋白质上的多组氨酸缀合

您好&#xff0c;欢迎来到新研之家 文章关键词&#xff1a;1854034-70-0&#xff0c;Bis-Sulfone-PEG4-DBCO&#xff0c;双巯基磺酸四聚乙二醇二苯基环辛炔 一、基本信息 【产品简介】&#xff1a;Bis Sulfone PEG4 DBCO contains disulfide groups, which gives it a uniqu…

SI522一款兼容RC522/FM17522 开发资料

SI522 是应用于13.56MHz 非接触式通信中高集成度读写卡系列芯片中的一员。是NXP 公司针对"三表"应用推出的一款低 电压、低成本、体积小的非接触式读写卡芯片&#xff0c;是智能仪表和便携 式手持设备研发的较好选择。 SI522利用了先进的调制和解调概念&#xff0c;完…

【Qt学习】多元素控件:QListWidget、QTableWidget 的介绍与使用

文章目录 1. QListWidget1.1 介绍1.2 使用 - 如何添加项目1.3 实例1.4 资源文件 2. QTableWidget2.1 介绍2.2 使用 - 添加项目的方式2.3 实例2.4 资源文件 3. QTreeWidget3.1 介绍3.2 使用 - 添加数据的方式3.3 实例3.4 资源文件 1. QListWidget 1.1 介绍 QListWidget 是 Qt …

【粉丝福利第一期】小 明

Q1 - 能否自我介绍下&#xff1f; 嗨&#xff0c;大家好&#xff0c;我是 小 明 &#xff08;小明java问道之路&#xff09;&#xff0c;互联网大厂后端研发专家&#xff0c;2022博客之星TOP3/博客专家/CSDN后端内容合伙人、InfoQ(极客时间)签约作者、阿里云签约博主、全网5万…

CentOS7如何使用Docker部署Wiki.Js知识库并实现公网远程访问?

文章目录 1. 安装Docker2. 获取Wiki.js镜像3. 本地服务器打开Wiki.js并添加知识库内容4. 实现公网访问Wiki.js5. 固定Wiki.js公网地址 不管是在企业中还是在自己的个人知识整理上&#xff0c;我们都需要通过某种方式来有条理的组织相应的知识架构&#xff0c;那么一个好的知识整…

请你画出一个微服务项目架构图

第一种 架构图 第二种 架构图