BFS算法篇——广度优先搜索,探索未知的旅程(上)

文章目录

  • 前言
  • 一、BFS的思路
  • 二、BFS的C语言实现
    • 1. 图的表示
    • 2. BFS的实现
  • 三、代码解析
  • 四、输出结果
  • 五、总结

在这里插入图片描述

前言

广度优先搜索(BFS)是一种广泛应用于图论中的算法,常用于寻找最短路径、图的遍历等问题。与深度优先搜索(DFS)不同,BFS通过层级地探索节点来确保最先访问的节点距离源点较近,因此它可以用来求解最短路径问题。让我们深入了解这个算法,并通过具体的例子和代码来进一步掌握它的实现。

一、BFS的思路

BFS的主要思想是从起始节点开始,首先访问该节点的所有邻接节点,然后再访问这些邻接节点的邻接节点。BFS利用队列的先进先出(FIFO)特性保证了节点是按层次顺序被访问的。

二、BFS的C语言实现

1. 图的表示

在C语言中,我们常用邻接表来表示图。对于无向图,我们可以使用一个邻接矩阵或者邻接链表。在这里,我们采用邻接链表表示图。

2. BFS的实现

以下是C语言实现BFS算法的具体代码,图使用邻接表表示:

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>#define MAX_NODES 6  // 节点数量// 图的邻接表结构
typedef struct Node {int data;struct Node* next;
} Node;typedef struct Graph {Node* adjList[MAX_NODES];
} Graph;// 队列结构
typedef struct Queue {int items[MAX_NODES];int front, rear;
} Queue;// 创建一个新的图
Graph* createGraph() {Graph* graph = (Graph*)malloc(sizeof(Graph));for (int i = 0; i < MAX_NODES; i++) {graph->adjList[i] = NULL;}return graph;
}// 向图中添加一条边
void addEdge(Graph* graph, int src, int dest) {Node* newNode = (Node*)malloc(sizeof(Node));newNode->data = dest;newNode->next = graph->adjList[src];graph->adjList[src] = newNode;// 因为是无向图,所以添加反向边newNode = (Node*)malloc(sizeof(Node));newNode->data = src;newNode->next = graph->adjList[dest];graph->adjList[dest] = newNode;
}// 初始化队列
void initQueue(Queue* q) {q->front = -1;q->rear = -1;
}// 入队
void enqueue(Queue* q, int value) {if (q->rear == MAX_NODES - 1) {printf("队列已满\n");return;}if (q->front == -1) {q->front = 0;}q->rear++;q->items[q->rear] = value;
}// 出队
int dequeue(Queue* q) {if (q->front == -1) {printf("队列为空\n");return -1;}int item = q->items[q->front];q->front++;if (q->front > q->rear) {q->front = q->rear = -1;}return item;
}// 判断队列是否为空
bool isQueueEmpty(Queue* q) {return q->front == -1;
}// 广度优先搜索BFS
void bfs(Graph* graph, int start) {bool visited[MAX_NODES] = {false};  // 访问标志数组Queue q;initQueue(&q);// 标记起始节点为已访问,并入队visited[start] = true;enqueue(&q, start);while (!isQueueEmpty(&q)) {// 出队并访问节点int node = dequeue(&q);printf("%c ", node + 'A');  // 输出节点(假设节点是字母A, B, C...)// 遍历当前节点的所有邻接节点Node* temp = graph->adjList[node];while (temp) {int adjNode = temp->data;if (!visited[adjNode]) {visited[adjNode] = true;enqueue(&q, adjNode);}temp = temp->next;}}
}int main() {// 创建图并添加边Graph* graph = createGraph();addEdge(graph, 0, 1);  // A - BaddEdge(graph, 0, 2);  // A - CaddEdge(graph, 1, 3);  // B - DaddEdge(graph, 1, 4);  // B - EaddEdge(graph, 2, 4);  // C - EaddEdge(graph, 3, 5);  // D - FaddEdge(graph, 4, 5);  // E - F// 执行BFS从节点A(索引0)开始printf("BFS遍历结果: ");bfs(graph, 0);// 释放内存free(graph);return 0;
}

三、代码解析

图的表示:

  • 图使用邻接表表示。每个节点用一个链表来存储与其直接相连的节点。Graph结构体中有一个数组 adjList 来保存所有节点的邻接链表。

队列的实现:

  • 队列用数组来实现,包含 front 和 rear 来管理队列的操作。队列用于按顺序访问图的每个节点。

BFS的实现:

  • 使用队列来管理待访问的节点。首先将起始节点标记为已访问并入队。然后逐步出队并访问节点,访问节点的邻接节点,如果邻接节点未被访问,则将其标记为已访问并入队。
  • 输出遍历的节点(假设节点为字母,如 A, B, C, …)。

四、输出结果

假设图的结构如下所示:

    A -- B -- D|    |    |C -- E -- F

输出结果将为:

BFS遍历结果: A B C D E F 

这意味着从节点 A 开始,BFS按层次遍历的顺序访问了图中的所有节点。

五、总结

  • BFS是一种通过逐层扩展来遍历图的算法,通常用于求解最短路径问题、图的遍历等。
  • 在C语言中,BFS通常使用队列来实现,队列的先进先出特性确保了图的层次遍历。
  • 本例中通过邻接表表示图,使用队列来实现BFS遍历,从而找到节点间的最短路径。
  • 广度优先搜索在实际问题中具有广泛的应用,例如在社交网络分析、路径规划等方面,都可以发挥其强大的作用。

本篇关于BFS算法篇的介绍就暂告段落啦,希望能对大家的学习产生帮助,欢迎各位佬前来支持斧正!!!

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

hot100(9)

81.104. 二叉树的最大深度 - 力扣&#xff08;LeetCode&#xff09; 后序遍历&#xff0c;从下往上&#xff0c;需要用到下面返回的结果。 public int maxDepth(TreeNode root) {if(root null){return 0;}int left maxDepth(root.left);int right maxDepth(root.right);re…

Elasticsearch:向量搜索的快速介绍

作者&#xff1a;来自 Elastic Valentin Crettaz 本文是三篇系列文章中的第一篇&#xff0c;将深入探讨向量搜索&#xff08;也称为语义搜索&#xff09;的复杂性&#xff0c;以及它在 Elasticsearch 中的实现方式。 本文是三篇系列文章中的第一篇&#xff0c;将深入探讨向量搜…

U9成品入库单有提示 组织+单号已经存在

2025年首个问题出来了&#xff01;也是U9上线以来首次碰到的问题。看到这样的提示&#xff0c;头皮发麻了。深感不妙。看过all.log之后&#xff0c;果然是重复行的问题&#xff01; 怎么会有重复行的错误发生呢&#xff1f;百思不得其解。 无奈之下&#xff0c;只能将单据类型…

为什么要设计DTO类/什么时候设置DTO类?

为什么设计DTO类&#xff1f; 例如&#xff1a;根据新增员工接口设计对应的DTO 前端传递参数列表&#xff1a; 思考&#xff1a;是否可以使用对应的实体类来接收呢&#xff1f; 注意&#xff1a;前端提交的数据和实体类中对应的属性差别比较大&#xff0c;所以自定义DTO类。 …

【C++篇】C++11新特性总结1

目录 1&#xff0c;C11的发展历史 2&#xff0c;列表初始化 2.1C98传统的{} 2.2&#xff0c;C11中的{} 2.3&#xff0c;C11中的std::initializer_list 3&#xff0c;右值引用和移动语义 3.1&#xff0c;左值和右值 3.2&#xff0c;左值引用和右值引用 3.3&#xff0c;…

大语言模型遇上自动驾驶:AsyncDriver如何巧妙解决推理瓶颈?

导读 这篇论文提出了AsyncDriver框架&#xff0c;致力于解决大语言模型在自动驾驶领域应用中的关键挑战。论文的主要创新点在于提出了大语言模型和实时规划器的异步推理机制&#xff0c;实现了在保持性能的同时显著降低计算开销。通过设计场景关联指令特征提取模块和自适应注入…

【iOS自动化】Xcode配置WebDriverAgent

WebDriverAgent 是 iOS 端自动化测试的工具&#xff0c;这里记录下 MacOS 环境 Xcode 如何配置 WebDriverAgent。 【重要】环境准备 ‼️ 注意&#xff1a;Xcode 版本需要支持对应的 iOS 版本&#xff0c;而 Xcode 版本又依赖 MacOS 版本&#xff1b;在开始部署前&#xff0c…

洛谷题目: P8774 [蓝桥杯 2022 省 A] 爬树的甲壳虫 题解 (本题较简)

题目传送门&#xff1a; P8774 [蓝桥杯 2022 省 A] 爬树的甲壳虫 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 前言&#xff1a; 这是一道关于概率和期望的动态规划问题&#xff0c;解题的核心思路是通过建立状态转移方程来计算甲壳虫从树根爬到树顶所需时间的期望值。题…

力扣题库第495题目解析

文章目录 1.题目再现2.思路分析&&示例说明2.1第一个示例2.2第二个示例 3.代码解释 1.题目再现 这个题目的名字叫做提莫攻击&#xff0c;如果是玩游戏的小伙伴对于这个场景就很熟悉了&#xff1b; 这个实际上是说&#xff1a;已知的条件会给我们一个数组&#xff0c;在…

leetcode刷题日记 1

https://leetcode.cn/problems/decode-ways/description/ 题目分析 分析了一下题目&#xff0c;我的第一想法&#xff1a;和之前的上楼梯问题很像 为什么这么说呢&#xff0c;感觉他们的值和他们之前元素都有千丝万缕的联系 就像上楼梯问题 就是我们的dp问题 怎么解释呢&a…

matlab simulink 汽车四分之一模型轮胎带阻尼

1、内容简介 略 matlab simulink121-汽车四分之一模型轮胎带阻尼 可以交流、咨询、答疑 2、内容说明 略 3、仿真分析 略 4、参考论文 略

广度优先搜索(BFS)算法详解——以走迷宫问题为例

引言&#xff1a;当算法遇见迷宫 想象你置身于一个复杂的迷宫&#xff0c;如何在最短时间内找到出口&#xff1f;这个问题不仅存在于童话故事中&#xff0c;更是计算机科学中经典的路径搜索问题。本文将带你通过走迷宫问题&#xff0c;深入理解广度优先搜索&#xff08;BFS&am…

网工_以太网MAC层

2025.02.05&#xff1a;网工老姜学习笔记 第12节 以太网MAC层 2.1 MAC层的硬件地址2.2 MAC地址特殊位含义2.3 终端适配器&#xff08;网卡&#xff09;具有过滤功能2.4 MAC帧的格式2.4.1 DIX Ethernet V2标准&#xff08;先私有&#xff0c;后开放&#xff0c;用得比较多&#…

解锁高效 Web 开发新姿势:Open WebUI 安装指南

在 Web 开发的浩瀚宇宙里&#xff0c;找到一款强大又好用的框架&#xff0c;就如同拥有了超级外挂&#xff0c;能让开发效率直线飙升。 今天要给大家介绍的 Open WebUI&#xff0c;便是这样一款神器&#xff0c;它作为开源框架&#xff0c;助力开发者轻松搭建现代感十足、交互性…

485网关数据收发测试

目录 1.UDP SERVER数据收发测试 使用产品&#xff1a; || ZQWL-GW1600NM 产品||【智嵌物联】智能网关型串口服务器 1.UDP SERVER数据收发测试 A&#xff08;TX&#xff09;连接RX B&#xff08;RX&#xff09;连接TX 打开1个网络调试助手&#xff0c;模拟用户的UDP客户端设…

软考高级-软件系统架构师-02-软件工程(重点)

用工程化的思想做软件 一、软件开发方法&#xff08;/原则&#xff09; 软件开发方法&#xff08;重点&#xff09; 结构化法&#xff08;面向过程/函数&#xff09; C 概念 用户至上严格区分工作阶段&#xff0c;每个阶段有各自的任务和成果强调系统开发的整体性和全局性系统开…

STM32的HAL库开发---通用定时器(TIMER)---定时器脉冲计数

一、脉冲计数实验原理 1、 外部时钟模式1&#xff1a;核心为蓝色部分的时基单元&#xff0c;时基单元的时钟源可以来自四种&#xff0c;分别是内部时钟PCLK、外部时钟模式1&#xff0c;外部时钟模式2、内部定时器触发&#xff08;级联&#xff09;。而脉冲计数就是使用外部时钟…

甘肃省医保刷脸设备激活步骤

医保刷脸设备激活开通操作流程 激活社保 一、拆下刷脸设备&#xff0c;按右侧按键设置Wi-Fi和内网 Wi-Fi可连接个人热点&#xff0c;用于获取安装地址 配置Wi-Fi成功以后&#xff0c;输入机构代码&#xff0c;点击“获取”&#xff0c;安装地址获取成功&#xff1b; 断开Wi-…

一个sql只能有一个order by

ORDER BY 子句在 SQL 中只能出现一次&#xff0c;静态部分和动态部分只能写一个 ORDER BY

【Linux网络编程】之守护进程

【Linux网络编程】之守护进程 进程组进程组的概念组长进程 会话会话的概念会话ID 控制终端控制终端的概念控制终端的作用会话、终端、bash三者的关系 前台进程与后台进程概念特点查看当前终端的后台进程前台进程与后台进程的切换 进程组 进程组的概念 当我们使用以下命令查与…