当前位置:   article > 正文

C语言经典算法之广度优先遍历算法_广度优先遍历c语言

广度优先遍历c语言

目录

前言

A.建议

B.简介

一 代码实现

二 时空复杂度

A.时间复杂度:

B.空间复杂度:

C.总结:

三 优缺点

A.优点:

B.缺点:

四 现实中的应用


前言

A.建议

1.学习算法最重要的是理解算法的每一步,而不是记住算法。

2.建议读者学习算法的时候,自己手动一步一步地运行算法。

tips:文中的对数均以2为底数

B.简介

图的广度优先遍历(BFS)是一种用于访问和处理图中节点的算法。从起始节点开始,逐层访问节点,先访问离起始节点最近的节点,然后逐层向外扩展。通过队列实现,保证按照广度顺序遍历,用于查找最短路径、连通性检测等。

一 代码实现

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. // 定义图的最大节点数
  4. #define MAX_NODES 100
  5. // 定义图的邻接表节点
  6. struct Node {
  7. int data;
  8. struct Node* next;
  9. };
  10. // 定义图
  11. struct Graph {
  12. int numNodes;
  13. struct Node* adjacencyList[MAX_NODES];
  14. int visited[MAX_NODES];
  15. };
  16. // 初始化图
  17. void initGraph(struct Graph* graph, int numNodes) {
  18. graph->numNodes = numNodes;
  19. for (int i = 0; i < numNodes; ++i) {
  20. graph->adjacencyList[i] = NULL;
  21. graph->visited[i] = 0;
  22. }
  23. }
  24. // 添加边
  25. void addEdge(struct Graph* graph, int src, int dest) {
  26. // 创建邻接表节点
  27. struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
  28. newNode->data = dest;
  29. newNode->next = graph->adjacencyList[src];
  30. graph->adjacencyList[src] = newNode;
  31. }
  32. // 广度优先遍历
  33. void BFS(struct Graph* graph, int startNode) {
  34. // 创建队列用于存储待访问节点
  35. int queue[MAX_NODES];
  36. int front = 0, rear = 0;
  37. // 将起始节点加入队列并标记为已访问
  38. queue[rear++] = startNode;
  39. graph->visited[startNode] = 1;
  40. // 开始遍历
  41. while (front < rear) {
  42. // 出队列
  43. int currentNode = queue[front++];
  44. printf("%d ", currentNode);
  45. // 遍历邻接节点
  46. struct Node* current = graph->adjacencyList[currentNode];
  47. while (current != NULL) {
  48. if (!graph->visited[current->data]) {
  49. // 将未访问的邻接节点加入队列并标记为已访问
  50. queue[rear++] = current->data;
  51. graph->visited[current->data] = 1;
  52. }
  53. current = current->next;
  54. }
  55. }
  56. }
  57. int main() {
  58. // 创建一个图并初始化
  59. struct Graph graph;
  60. initGraph(&graph, 6);
  61. // 添加图的边
  62. addEdge(&graph, 0, 1);
  63. addEdge(&graph, 0, 2);
  64. addEdge(&graph, 1, 3);
  65. addEdge(&graph, 2, 4);
  66. addEdge(&graph, 3, 5);
  67. // 执行广度优先遍历
  68. printf("Breadth-First Traversal: ");
  69. BFS(&graph, 0);
  70. return 0;
  71. }

这个例子中,通过队列实现了广度优先遍历,起始节点首先入队列,然后从队列中出队列并将其未访问的邻接节点入队列,直到队列为空。这样可以确保按照广度优先的顺序遍历图的节点。

二 时空复杂度


A.时间复杂度

时间复杂度为O(V + E),其中V是节点数,E是边数。对每个节点和每条边进行访问一次。
每个节点入队和出队一次,每条边的两个节点分别入队一次。


B.空间复杂度

空间复杂度为O(V),其中V是节点数。需要使用队列来存储待访问的节点,队列中的节点数不会超过图的节点数。使用一个数组或集合来标记节点是否已访问过,占用的空间也与节点数成正比。

C.总结:

广度优先遍历的时间复杂度主要由节点数和边数决定,而空间复杂度则主要受到节点数的影响。在实际应用中,BFS对于稀疏图相对较为高效,因为它会在每一层扩展前完成对当前层的遍历

三 优缺点


A.优点:


最短路径: BFS能够找到起始节点到其他节点的最短路径,因为它按照层级遍历,首次到达目标节点的路径就是最短路径。

连通性检测: BFS可以有效地检测图中的连通分量,判断图的连通性。

最小生成树: 在无权图中,BFS可以用于构建最小生成树。

网络路由: 用于计算网络中节点之间的最短路径,影响路由算法的设计。

图的遍历: 能够以层级的方式遍历图中的节点,使其更易于理解。

B.缺点:


空间复杂度较高: BFS使用队列来存储待访问节点,可能在图较大时占用较多内存,不适用于大规模图的处理。

非最优路径: 对于权重不同的有向图,BFS找到的路径不一定是最优路径,因为它并未考虑边的权重。

不适用于大规模图: 在某些情况下,BFS需要遍历大量节点和边,可能导致性能下降,不适用于大规模图的处理。

不适用于处理带权图: 在有权图中,BFS通常无法找到最短路径,需要使用其他算法如Dijkstra's或A*。

可能存在环的问题: 在无向图中,BFS在检测环时可能需要额外的处理,以防止重复访问节点。

四 现实中的应用


广度优先遍历算法在现实中有多种应用,特别适用于需要按层级展开搜索的问题。以下是一些广度优先遍历在现实中的应用:

社交网络分析: 在社交网络中,广度优先遍历用于查找用户之间的关系,发现社交圈子,推荐朋友或关注。

网络路由: 广度优先遍历用于计算网络中节点之间的最短路径,影响路由算法的设计,确保信息以最短路径传递。

最短路径搜索: 用于查找从起始位置到目标位置的最短路径,例如在地图导航应用中。

图像处理: 广度优先遍历可用于图像分割、对象提取和区域填充,通过像素之间的连接性进行处理。

文件系统和目录遍历: 在文件系统中,广度优先遍历用于按照层级结构遍历文件和目录,确保按照文件夹层级展开。

连通性检测: 用于检测图中的连通分量,判断一个图是否是强连通图,或者找到图中的孤立子图。

电路设计和信号传播: 广度优先遍历可用于电路设计中的信号传播,确保信号以最短路径传递。

人工智能: 在搜索算法中,广度优先遍历可以用于状态空间的搜索,寻找解决问题的最短路径。

网页爬取: 在网络爬虫中,广度优先遍历用于遍历和爬取网站上的链接,确保以层级方式获取页面信息。

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Monodyee/article/detail/695409
推荐阅读
相关标签
  

闽ICP备14008679号