前言
适用于已知起点与终点的最短路径搜索。
一、BFS是什么?
BFS(Breadth-First Search),广度优先搜索。即从任意节点开始,逐层级遍历所有相邻节点。
二、代码详情
代码如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BFS{
List<List<int>> NodesList = new List<List<int>>();//各节点及其相邻节点
List<int> ParentNodeList = new List<int>();//存储上层节点
public BFS(List<Node> nodes)//数据初始化
{
Init_NodesList(nodes);
Init_ParentNodeList();
}
private void Init_NodesList(List<AdjacentCity> nodes)
{
NodesList.Clear();
foreach (AdjacentCity child in nodes)//节点数据存储结构转换-由自定义结构转为List<List<int>>
{
NodesList.Add(child.AdjacentCitys);
}
}
private void Init_ParentNodeList()
{
ParentNodeList.Clear();
for (int i = 0; i < 50; i++)//初始化 上层节点List
{
ParentNodeList.Add(-1);//-1表示当前节点为根节点
}
}
public List<int> Get_ShortestPathByBFS(int start, int end)
{
Queue<int> queue = new Queue<int>();//节点队列,按照层级入队
HashSet<int> seen = new HashSet<int>();//被使用的节点 哈希集合
queue.Enqueue(start);
seen.Add(start);
while (queue.Count > 0)//队列中存在节点
{
int vertex = queue.Dequeue(); //当前子层的父节点
List<int> nodes = NodesList[vertex];
foreach (var child in nodes)
{
if (child == end)//查找到终点
{
seen.Add(child);
ParentNodeList[child] = vertex;
queue.Clear();//查找到结果,清空队列
break;//结束当前子层循环
}
else//当前节点不是终点
{
if (!seen.Contains(child))//当前节点未被使用,更新当前节点信息
{
queue.Enqueue(child);
seen.Add(child);
ParentNodeList[child] = vertex;
}
}
}
}
List<int> pathNodes = new List<int>();//List方便数据反转
pathNodes = Return_PathNodes(end, pathNodes);
pathNodes.Reverse();//数据反转,由终点到起点 转换为 起点到终点
return pathNodes;//返回-查找到的最短路径
}
private List<int> Return_PathNodes(int nowNode, List<int> pathNodes)//根据上层节点List,由终点逆推回起点
{
pathNodes.Add(nowNode);//保存当前节点
if (ParentNodeList[nowNode] == -1)//查找到根节点,结束递归(当前节点的父节点为-1)
{
return pathNodes;
}
else//查找上层节点
{
return Return_PathNodes(ParentNodeList[nowNode], pathNodes);
}
}
}
总结
1、BFS函数-初始化节点数据2、Get_ShortestPathByBFS函数-得到最短路径
注意:a、Init_NodesList函数对自定义节点结构进行转换
b、需添加命名空间