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

news2025/3/14 19:10:06

文章目录

  • 前言
  • 一、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 - B
    addEdge(graph, 0, 2);  // A - C
    addEdge(graph, 1, 3);  // B - D
    addEdge(graph, 1, 4);  // B - E
    addEdge(graph, 2, 4);  // C - E
    addEdge(graph, 3, 5);  // D - F
    addEdge(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.coloradmin.cn/o/2295933.html

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

相关文章

Django开发入门 – 0.Django基本介绍

Django开发入门 – 0.Django基本介绍 A Brief Introduction to django By JacksonML 1. Django简介 1) 什么是Django? 依据其官网的一段解释&#xff1a; Django is a high-level Python web framework that encourages rapid development and clean, pragmatic design. …

idea整合deepseek实现AI辅助编程

1.File->Settings 2.安装插件codegpt 3.注册deepseek开发者账号&#xff0c;DeepSeek开放平台 4.按下图指示创建API KEY 5.回到idea配置api信息&#xff0c;File->Settings->Tools->CodeGPT->Providers->Custom OpenAI API key填写deepseek的api key Chat…

加速汽车软件升级——堆栈刷写技术的应用与挑战

一、背景和挑战 | 背景&#xff1a; 当前汽车市场竞争激烈&#xff0c;多品牌并存&#xff0c;新车发布速度加快&#xff0c;价格逐渐降低&#xff0c;功能日益多样化。随着车辆功能的不断提升与优化&#xff0c;ECU&#xff08;电子控制单元&#xff09;的代码量也随之增加&…

2. UVM的基本概念和架构

文章目录 前言1. UVM的基本概念1.1 UVM的核心组件1.2 UVM的基本架构1.3 UVM的工作流程 2. UVM的架构2.1 UVM的层次结构2.2 UVM的组件交互 3. 总结 前言 首先&#xff0c;得确定UVM的基本概念和架构包含哪些关键部分。我回忆起UVM的核心组件&#xff0c;比如uvm_component、uvm…

【力扣】138.随机链表的复制

AC截图 题目 代码 使用哈希存储<旧节点&#xff0c;新结点> /* // Definition for a Node. class Node { public:int val;Node* next;Node* random;Node(int _val) {val _val;next NULL;random NULL;} }; */class Solution { public:Node* copyRandomList(Node* hea…

归一化与伪彩:LabVIEW图像处理的区别

在LabVIEW的图像处理领域&#xff0c;归一化&#xff08;Normalization&#xff09;和伪彩&#xff08;Pseudo-coloring&#xff09;是两个不同的概念&#xff0c;虽然它们都涉及图像像素值的调整&#xff0c;但目的和实现方式截然不同。归一化用于调整像素值的范围&#xff0c…

Ollama + AnythingLLM + Deepseek r1 实现本地知识库

1、Ollama&#xff1a;‌是一个开源的大型语言模型 (LLM)服务工具&#xff0c;旨在简化在本地运行大语言模型的过程&#xff0c;降低使用大语言模型的门槛‌。 2、AnythingLLM&#xff1a;是由Mintplex Labs Inc. 开发的一款全栈应用程序&#xff0c;旨在构建一个高效、可定制、…

Deepseek-v3 / Dify api接入飞书机器人go程序

准备工作 开通了接收消息权限的飞书机器人&#xff0c;例如我希望用户跟飞书机器人私聊&#xff0c;就需要开通这个权限&#xff1a;读取用户发给机器人的单聊消息 im:message.p2p_msg:readonly准备好飞书机器人的API key 和Secretdeepseek-v3的api keysecret&#xff1a;http…

详解策略模式

引言 实现一个目标往往有多种方式&#xff0c;比如从上海到北京&#xff0c;可以选择高铁、火车、飞机、自驾等等。同样实现一个功能我们可能也有多种方法&#xff0c;把这些方法封装为算法&#xff0c;根据不同的需求选择不同的算法&#xff08;策略&#xff09;&#xff0c;让…

2025影视泛目录站群程序设计_源码二次开发新版本无缓存刷新不变实现原理

1. 引言 本设站群程序计书旨在详细阐述苹果CMS泛目录的创新设计与实现&#xff0c;介绍无缓存刷新技术、数据统一化、局部URL控制及性能优化等核心功能&#xff0c;以提升网站访问速度和用户体验。 2. 技术概述 2.1 无缓存刷新技术 功能特点&#xff1a; 内容不变性&#x…

【RabbitMQ】RabbitMQ的下载安装及使用

安装RabbitMQ 下载网站&#xff1a;https://www.rabbitmq.com/docs/install-windows 点击后&#xff0c;会直接定位到依赖介绍位置&#xff0c;告诉你需要安装Erlang 下载Erlang Erlang也是一种编程语言&#xff0c;只是比较小众&#xff0c;但其拥有极为出色的性能 这个网站是…

Stylelint 如何处理 CSS 预处理器

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

Word中Ctrl+V粘贴报错问题

Word中CtrlV粘贴时显示“文件未找到&#xff1a;MathPage.WLL”的问题 Word的功能栏中有MathType&#xff0c;但无法使用&#xff0c;显示灰色。 解决方法如下&#xff1a; 首先找到MathType安装目录下MathPage.wll文件以及MathType Commands 2016.dotm文件&#xff0c;分别复…

jmeter逻辑控制器9

1&#xff0c;简单控制器2&#xff0c;录制控制器3&#xff0c;循环控制器4&#xff0c;随机控制器5&#xff0c;随机顺序控制器6&#xff0c;if控制器7&#xff0c;模块控制器8&#xff0c;Include控制器9&#xff0c;事物控制器本文永久更新地址: 1&#xff0c;简单控制器 不…

GitHub Copilot Agent 模式系统提示词

系统提示词 你是一名 AI 编程助手。 当被问及你的名字时&#xff0c;你必须回答“GitHub Copilot”。请严格且完整地遵循用户的要求。 遵守微软内容政策。 避免涉及侵犯版权的内容。如果有人要求你生成有害、仇恨、种族主义、性别歧视、淫秽、暴力或与软件工程完全无关的内容&…

【设计模式】【行为型模式】模板方法模式(Template Method)

&#x1f44b;hi&#xff0c;我不是一名外包公司的员工&#xff0c;也不会偷吃茶水间的零食&#xff0c;我的梦想是能写高端CRUD &#x1f525; 2025本人正在沉淀中… 博客更新速度 &#x1f4eb; 欢迎V&#xff1a; flzjcsg2&#xff0c;我们共同讨论Java深渊的奥秘 &#x1f…

w200基于spring boot的个人博客系统的设计与实现

&#x1f64a;作者简介&#xff1a;多年一线开发工作经验&#xff0c;原创团队&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的网站项目。 代码可以查看文章末尾⬇️联系方式获取&#xff0c;记得注明来意哦~&#x1f339;赠送计算机毕业设计600个选题excel文…

docker grafana安装

mkdir /root/grafana-storage chmod 777 -R /root/grafana-storage docker run -d -p 3000:3000 --namedocker-apisix-grafana-1 --network docker-apisix_apisix -v /root/grafana-storage:/var/lib/grafana grafana/grafana:9.1.0 浏览器访问&#xff1a; http://192.…

H5+CSS+JS制作好看的轮播图

先来看效果 点击下方按钮可以做到平滑切换轮播&#xff0c;轮播图片可以根据自定义随心变化。 先来看一下页面代码结构 <div class"container"><div class"lunbo-wrap"><div id"slide"></div><div class"butto…

表单与交互:HTML表单标签全面解析

目录 前言 一.HTML表单的基本结构 基本结构 示例 二.常用表单控件 文本输入框 选择控件 文件上传 按钮 综合案例 三.标签的作用 四.注意事项 前言 HTML&#xff08;超文本标记语言&#xff09;是构建网页的基础&#xff0c;其中表单&#xff08;<form>&…