广度优先搜索思想

图的广度优先搜索(Broad First Search)
类似于一个分层搜索的过层,广度优先遍历需要使用一个队列以保持访问的结点的顺序,以便于按这个顺序来访问这些节点的邻接节点。

广度优先吧遍历算法的步骤

  1. 访问初始节点v并标记节点v为已访问
  2. 节点v入队列
  3. 当队列非空时,继续执行,否则算法结束(对v这个节点算法结束)
  4. 出队列,取得队头节点u
  5. 查找节点u的第一个邻接节点w
  6. 若节点u的邻接节点w不存在,则转到步骤3;否则循环执行以下三个步骤:
    1. 若节点w尚未被访问,则访问节点w并标记为已访问
    2. 节点w入队列
    3. 查找节点u的继w邻接节点后的下一个邻接节点w,转到步骤6

      代码

      ```csharp using System; using System.Collections.Generic; using System.Text;

namespace ConsoleApp1 { public class Graph { public List vertexList;//存储顶点集合 public int[,] edges;//存储图对应的邻接矩阵 public int numOfEdges;//表示边的数目 public bool[] isVisited;//存放顶点是否被访问

  1. public Graph(int n)//n顶点的个数
  2. {
  3. //初始化矩阵和vertexList
  4. edges = new int[n, n];
  5. vertexList = new List<string>(n);
  6. isVisited = new bool[n];
  7. }
  8. //插入顶点
  9. public void insertVertex(string vertex)
  10. {
  11. vertexList.Add(vertex);
  12. }
  13. /// <summary>
  14. /// 添加边
  15. /// </summary>
  16. /// <param name="v1">第一个顶点的下标</param>
  17. /// <param name="v2">第二个顶点的下标</param>
  18. /// <param name="weight">权值</param>
  19. public void insertEdge(int v1,int v2,int weight)
  20. {
  21. //因为是无向表,所以v1-v2和v2-v1都需要标记
  22. edges[v1, v2] = weight;
  23. edges[v2, v1] = weight;
  24. numOfEdges++;//两点之间只有一条边
  25. }
  26. //显示图对应的矩阵
  27. public void showGraph()
  28. {
  29. for(int i = 0; i < edges.GetLength(0); i++)
  30. {
  31. for(int t = 0; t < edges.GetLength(1); t++)
  32. {
  33. Console.Write(edges[i,t]+" ");
  34. }
  35. Console.WriteLine();
  36. }
  37. }
  38. #region 广度优先搜索
  39. //得到第一个邻接节点的下标w
  40. public int getFirstNeighbor(int index)
  41. {
  42. for (int j = 0; j < vertexList.Count; j++)
  43. {
  44. if (edges[index, j] > 0)
  45. return j;
  46. }
  47. return -1;
  48. }
  49. //根据前一个邻接节点的下标,来获取下一个邻接节点
  50. public int getNextNeighbor(int v1, int v2)
  51. {
  52. for (int j = v2 + 1; j < vertexList.Count; j++)
  53. {
  54. if (edges[v1, j] > 0)
  55. return j;
  56. }
  57. return -1;
  58. }
  59. public void BFS(bool[] isVisited,int i)
  60. {
  61. int u;//队列头结点对应的下标
  62. int w;//邻接节点w
  63. //队列,记录节点访问的顺序
  64. Queue<int> queue = new Queue<int>();
  65. //访问节点,输出信息
  66. Console.Write(vertexList[i]+"->");
  67. //标记为已访问
  68. isVisited[i] = true;
  69. //将节点加入队列
  70. queue.Enqueue(i);
  71. while (queue.Count > 0)
  72. {
  73. //取出队列的头结点
  74. u = queue.Dequeue();
  75. //得到第一个
  76. w = getFirstNeighbor(u);
  77. while (w != -1)//只要不等于-1就是找到了
  78. {
  79. if(!isVisited[w])//没访问过
  80. {
  81. Console.Write(vertexList[w] + "->");
  82. //标记为已经访问
  83. isVisited[w] = true;
  84. //入队列
  85. queue.Enqueue(w);
  86. }
  87. //已经访问过了,以u的前驱点找w的后一个邻接点
  88. w = getNextNeighbor(u, w);//广度优先
  89. }
  90. }
  91. }
  92. //遍历所有的节点,进行广度优先算法
  93. public void BFS()
  94. {
  95. for(int i = 0; i < vertexList.Count; i++)
  96. {
  97. if (!isVisited[i])
  98. BFS(isVisited, i);
  99. }
  100. }
  101. #endregion
  102. }

}

```