广度优先搜索思想
图的广度优先搜索(Broad First Search)
类似于一个分层搜索的过层,广度优先遍历需要使用一个队列以保持访问的结点的顺序,以便于按这个顺序来访问这些节点的邻接节点。
广度优先吧遍历算法的步骤
- 访问初始节点v并标记节点v为已访问
- 节点v入队列
- 当队列非空时,继续执行,否则算法结束(对v这个节点算法结束)
- 出队列,取得队头节点u
- 查找节点u的第一个邻接节点w
- 若节点u的邻接节点w不存在,则转到步骤3;否则循环执行以下三个步骤:
namespace ConsoleApp1
{
public class Graph
{
public List
public Graph(int n)//n顶点的个数
{
//初始化矩阵和vertexList
edges = new int[n, n];
vertexList = new List<string>(n);
isVisited = new bool[n];
}
//插入顶点
public void insertVertex(string vertex)
{
vertexList.Add(vertex);
}
/// <summary>
/// 添加边
/// </summary>
/// <param name="v1">第一个顶点的下标</param>
/// <param name="v2">第二个顶点的下标</param>
/// <param name="weight">权值</param>
public void insertEdge(int v1,int v2,int weight)
{
//因为是无向表,所以v1-v2和v2-v1都需要标记
edges[v1, v2] = weight;
edges[v2, v1] = weight;
numOfEdges++;//两点之间只有一条边
}
//显示图对应的矩阵
public void showGraph()
{
for(int i = 0; i < edges.GetLength(0); i++)
{
for(int t = 0; t < edges.GetLength(1); t++)
{
Console.Write(edges[i,t]+" ");
}
Console.WriteLine();
}
}
#region 广度优先搜索
//得到第一个邻接节点的下标w
public int getFirstNeighbor(int index)
{
for (int j = 0; j < vertexList.Count; j++)
{
if (edges[index, j] > 0)
return j;
}
return -1;
}
//根据前一个邻接节点的下标,来获取下一个邻接节点
public int getNextNeighbor(int v1, int v2)
{
for (int j = v2 + 1; j < vertexList.Count; j++)
{
if (edges[v1, j] > 0)
return j;
}
return -1;
}
public void BFS(bool[] isVisited,int i)
{
int u;//队列头结点对应的下标
int w;//邻接节点w
//队列,记录节点访问的顺序
Queue<int> queue = new Queue<int>();
//访问节点,输出信息
Console.Write(vertexList[i]+"->");
//标记为已访问
isVisited[i] = true;
//将节点加入队列
queue.Enqueue(i);
while (queue.Count > 0)
{
//取出队列的头结点
u = queue.Dequeue();
//得到第一个
w = getFirstNeighbor(u);
while (w != -1)//只要不等于-1就是找到了
{
if(!isVisited[w])//没访问过
{
Console.Write(vertexList[w] + "->");
//标记为已经访问
isVisited[w] = true;
//入队列
queue.Enqueue(w);
}
//已经访问过了,以u的前驱点找w的后一个邻接点
w = getNextNeighbor(u, w);//广度优先
}
}
}
//遍历所有的节点,进行广度优先算法
public void BFS()
{
for(int i = 0; i < vertexList.Count; i++)
{
if (!isVisited[i])
BFS(isVisited, i);
}
}
#endregion
}
}
```