用C++类和队列实现图搜索的广度优先遍历算法

简介: 用C++类和队列实现图搜索的广度优先遍历算法

广度优先遍历概念


出现背景:


求解节点间的最短路径,因为它的特点是 "搜到就是最优解"。


定义:


广度优先搜索(Breadth-First Search),又称作宽度优先搜索。BFS是一种完备策略,即只要问题有解,它就一定可以找到解。并且,广度优先搜索找到的解,还一定是路径最短的解。但是它盲目性较大,尤其是当目标节点距初始节点较远时,将产生许多无用的节点,因此其搜索效率较低。一般只有需求最优解的时候会用BFS。


本案例示意图



要求:


使用广度优先遍历算法输出访问结点的顺序,结果为0、1、2、4、5、8、9、3、6、7、10


邻接矩阵的设计



按照案例给出的图,我简化成了这个邻接矩阵,画法就是,两个结点之间相连设置为T,不相连设置为F,规定结点自身与自身不相连,当然对T和F要有声明,例如 const bool T =true,F=false;这样T就代表通路,F就代表断路了。


代码实现


#include<iostream>
using namespace std;
const int n = 11;//结点个数
const int SIZE = 10;
class queue
{
private:
  int buffer[SIZE];
  int rear, head;//rear指向队尾元素,front指向队列前一格
  int update(int value) { return (value + 1) % SIZE; }
public:
  queue():head(0),rear(0){}
  bool queueNull() { return rear == head;}//队空队尾下标和队首下标相同
  bool queueMax() { return update(rear) == head; } //队满
  bool queueAdd(int E)
  {
  if (queueMax()) return false;
  rear = update(rear);
  buffer[rear] = E;
  return true;
  }
  bool getFirstQueue(int& E)
  {
  if (queueNull()) return false;
  head = update(head);
  E = buffer[head];
  return true;
  }
};
const bool F = false, T = true;
bool nextClose[n][n] = {
    {F,T,T,F,F,F,F,F,F,F,F},
    {T,F,F,F,T,T,F,F,F,F,F},
    {T,F,F,F,F,F,F,F,T,T,F},
    {F,F,F,F,T,F,F,F,F,F,F},
    {F,T,F,T,F,F,T,F,F,F,F},
    {F,T,F,F,F,F,F,T,F,F,T},
    {F,F,F,F,T,F,F,F,F,F,F},
    {F,F,F,F,F,T,F,F,F,F,F},
    {F,F,T,F,F,F,F,F,F,F,F},
    {F,F,T,F,F,F,F,F,F,F,F},
    {F,F,F,F,F,T,F,F,F,F,F}
};
bool flag[n];
void BreadthFirstSearch(int begin)
{
  for (int i = 0; i < n; i++) flag[i] = false;
  queue que;//创建队列对象
  que.queueAdd(begin);
  flag[begin] = true;
  int node;
  while (!que.queueNull())
  {
  que.getFirstQueue(node);
  cout << node << ",";
  for (int i=0;i<n;i++)
  {
    if (nextClose[node][i] && !flag[i])
    {
    que.queueAdd(i);
    flag[i] = true;
    }
  }
  }
}
int main()
{
  BreadthFirstSearch(0);
  cout << "Hello World" << endl;
}


运行结果:



关键代码详解


相信使用类来做这个案例,很多入门的朋友都会很疑惑,对这方面知识了解比较少,所以我把最重要的两部分队列类和bfs具体实现详解一下

关于类


const int n = 11;//结点个数
const int SIZE = 10;
class queue
{
private:
  int buffer[SIZE];
  int rear, head;//rear指向队尾元素,front指向队列前一格
  int update(int value) { return (value + 1) % SIZE; }
public:
  queue():head(0),rear(0){}
  bool queueNull() { return rear == head;}//队空队尾下标和队首下标相同
  bool queueMax() { return update(rear) == head; } //队满
  bool queueAdd(int E)
  {
  if (queueMax()) return false;
  rear = update(rear);
  buffer[rear] = E;
  return true;
  }
  bool getFirstQueue(int& E)
  {
  if (queueNull()) return false;
  head = update(head);
  E = buffer[head];
  return true;
  }
};


首先私有的属性有 长度为10的buffer整型数组、用来指向数组的rear和head下标,和一个undate方法用来使rear和head的指向往下进行,对10求余就是得到个位数,由于是加1后求余,所以会逐步往下进行;公有区域下第一个就是queue的无参构造了,他利用初始化列表给head和rear的初始化为0;下面queueNull 是队空的判断(rear=head);queMax 是队满的判断,让rear或者head下标重置为零;queAdd 是追加方法,将数据加到buffer队列中,如果队满,不能追加,方法结束,当队非满时,尾下标加一,将输入数据加入到队列第二个空中;而getFirstQueue 方法是取队首元素的方法,当队非空时,head下标加一,取出队列第二格元素。


关于bfs的具体实现


bool flag[n];
void BreadthFirstSearch(int begin)
{
  for (int i = 0; i < n; i++) flag[i] = false;
  queue que;//创建队列对象
  que.queueAdd(begin);
  flag[begin] = true;
  int node;
  while (!que.queueNull())
  {
  que.getFirstQueue(node);
  cout << node << ",";
  for (int i=0;i<n;i++)
  {
    if (nextClose[node][i] && !flag[i])
    {
    que.queueAdd(i);
    flag[i] = true;
    }
  }
  }
}


假设begin为0结点,先把标志位flag数组全置为false,接下来添加0结点到队列第二个格子,并把标志位置为true,定义node,取出0结点并输出,代表已经访问过,后面的一重循环是为了把当前结点相连的结点全部追加到队列中,当然已经访问的不会追加,追加后把该结点标志位置为true;rear 和 head 下标会随着元素的追加不断变大,当下标大于队列长度n时,又变为从零开始增大,不追加元素的时候,rear不变,等head慢慢接近rear,当二者相等时,程序结束。


五图助理解


初始状态,此时rear和head均为0,将结点0待添加



将结点0插入buffer[1],并将与0结点连接的1、2结点追加到队列中,rear指向队尾,head取队首元素0,停留在1处,下一次循环head加1,继续追加和结点1相连的结点



这次head停留在2处,追加了与1结点相连的4、5结点,rear依然指向队尾



这里显示rear即将大于队列长度的情况,此时把head指向的4结点连接的结点3、6追加到队列中



继续加连接5结点的7、10结点,但是上一次队列已满,经过 return value=(value+1)%10,rear变为0,最终变为一,停留在1上,后续不再增加结点。随着循环的进行,head不断往后走,直到大于队列,重置为0,1,等于rear时,循环结束,rear==head,整个程序结束。



调试界面


浅看一下调试结果,在取队首和追加结点之间加断点调试debug,head等于9时,输出结点值6,当head等于1时,输出结点时,再调试程序就会退出,因为rear=head,队满程序结束。




相关文章
|
13天前
|
机器学习/深度学习 算法 安全
【无人机三维路径规划】基于非支配排序的鲸鱼优化算法NSWOA与多目标螳螂搜索算法MOMSA求解无人机三维路径规划研究(Matlab代码实现)
【无人机三维路径规划】基于非支配排序的鲸鱼优化算法NSWOA与多目标螳螂搜索算法MOMSA求解无人机三维路径规划研究(Matlab代码实现)
|
15天前
|
机器学习/深度学习 算法 安全
【无人机三维路径规划】多目标螳螂搜索算法MOMSA与非支配排序的鲸鱼优化算法NSWOA求解无人机三维路径规划研究(Matlab代码实现)
【无人机三维路径规划】多目标螳螂搜索算法MOMSA与非支配排序的鲸鱼优化算法NSWOA求解无人机三维路径规划研究(Matlab代码实现)
|
2月前
|
机器学习/深度学习 算法 文件存储
神经架构搜索NAS详解:三种核心算法原理与Python实战代码
神经架构搜索(NAS)正被广泛应用于大模型及语言/视觉模型设计,如LangVision-LoRA-NAS、Jet-Nemotron等。本文回顾NAS核心技术,解析其自动化设计原理,探讨强化学习、进化算法与梯度方法的应用与差异,揭示NAS在大模型时代的潜力与挑战。
295 6
神经架构搜索NAS详解:三种核心算法原理与Python实战代码
|
5月前
|
存储 监控 算法
基于 C++ 哈希表算法实现局域网监控电脑屏幕的数据加速机制研究
企业网络安全与办公管理需求日益复杂的学术语境下,局域网监控电脑屏幕作为保障信息安全、规范员工操作的重要手段,已然成为网络安全领域的关键研究对象。其作用类似网络空间中的 “电子眼”,实时捕获每台电脑屏幕上的操作动态。然而,面对海量监控数据,实现高效数据存储与快速检索,已成为提升监控系统性能的核心挑战。本文聚焦于 C++ 语言中的哈希表算法,深入探究其如何成为局域网监控电脑屏幕数据处理的 “加速引擎”,并通过详尽的代码示例,展现其强大功能与应用价值。
110 2
|
16天前
|
存储 算法 数据可视化
基于禁忌搜索算法的TSP问题最优路径搜索matlab仿真
本程序基于禁忌搜索算法解决旅行商问题(TSP),旨在寻找访问多个城市的最短路径。使用 MATLAB 2022A 编写,包含城市坐标生成、路径优化及结果可视化功能。通过禁忌列表、禁忌长度与藐视准则等机制,提升搜索效率与解的质量,适用于物流配送、路径规划等场景。
|
2月前
|
机器学习/深度学习 并行计算 算法
MATLAB实现利用禁忌搜索算法解决基站选址问题
MATLAB实现利用禁忌搜索算法解决基站选址问题
67 0
|
3月前
|
存储 搜索推荐 算法
加密算法、排序算法、字符串处理及搜索算法详解
本文涵盖四大类核心技术知识。加密算法部分介绍了对称加密(如 AES)、非对称加密(如 RSA)、哈希摘要(如 SHA-2)、签名算法的特点及密码存储方案(加盐、BCrypt 等)。 排序算法部分分类讲解了比较排序(冒泡、选择、插入、归并、快排、堆排序)和非比较排序(计数、桶、基数排序)的时间复杂度、适用场景及实现思路,强调混合排序的工业应用。 字符串处理部分包括字符串反转的双指针法,及项目中用正则进行表单校验、网页爬取、日志处理的实例。 搜索算法部分详解了二分查找的实现(双指针与中间索引计算)和回溯算法的概念(递归 + 剪枝),以 N 皇后问题为例说明回溯应用。内容全面覆盖算法原理与实践
130 0
|
3月前
|
存储 监控 算法
基于跳表数据结构的企业局域网监控异常连接实时检测 C++ 算法研究
跳表(Skip List)是一种基于概率的数据结构,适用于企业局域网监控中海量连接记录的高效处理。其通过多层索引机制实现快速查找、插入和删除操作,时间复杂度为 $O(\log n)$,优于链表和平衡树。跳表在异常连接识别、黑名单管理和历史记录溯源等场景中表现出色,具备实现简单、支持范围查询等优势,是企业网络监控中动态数据管理的理想选择。
84 0
|
4月前
|
存储 机器学习/深度学习 算法
基于 C++ 的局域网访问控制列表(ACL)实现及局域网限制上网软件算法研究
本文探讨局域网限制上网软件中访问控制列表(ACL)的应用,分析其通过规则匹配管理网络资源访问的核心机制。基于C++实现ACL算法原型,展示其灵活性与安全性。文中强调ACL在企业与教育场景下的重要作用,并提出性能优化及结合机器学习等未来研究方向。
100 4
|
5月前
|
监控 算法 数据处理
基于 C++ 的 KD 树算法在监控局域网屏幕中的理论剖析与工程实践研究
本文探讨了KD树在局域网屏幕监控中的应用,通过C++实现其构建与查询功能,显著提升多维数据处理效率。KD树作为一种二叉空间划分结构,适用于屏幕图像特征匹配、异常画面检测及数据压缩传输优化等场景。相比传统方法,基于KD树的方案检索效率提升2-3个数量级,但高维数据退化和动态更新等问题仍需进一步研究。未来可通过融合其他数据结构、引入深度学习及开发增量式更新算法等方式优化性能。
145 17

热门文章

最新文章