广度优先算法(Breadth-First Search)是在图和树领域的搜索方法,其核心思想是从一个起始点开始,访问其所有的临近节点,然后再按照相同的方式访问这些临近节点的节点,这种访问方式类似涟漪泛起,一层一层的扩散。
广度优先算法解决的问题:
- 从A点出发,有没有一条路径可以到达B点
- 如果有的话,能不能找到最短的路径。
- 图/树的遍历
广度优先算法的实现(C++):
要遍历的图结构:
using System;
using System.Collections;
using System.Reflection;
using UnityEngine;
namespace Framwork
{
/// <summary>
/// Playerprefs 存储类
/// </summary>
public class PlayerPrefsManager
{
private static PlayerPrefsManager instance=new PlayerPrefsManager();
public static PlayerPrefsManager Instance => instance;
private PlayerPrefsManager()
{
}
/// <summary>
/// 存取数据的方法
/// </summary>
/// <param name="obj">数据实体</param>
/// <param name="name">数据名称</param>
public void SaveData(object data, string keyName)
{
Type type = data.GetType();
FieldInfo[] infos = type.GetFields();
string tempKey="null";
FieldInfo tempInfo = null;
for (int i = 0; i < infos.Length; i++)
{
//获取数据数据类型
tempInfo = infos[i];
Debug.Log("Types==="+tempInfo);
//类的名字+类的类型 + 数据内容名字+数据类型
//作为存储的keyName键
tempKey = keyName + "_" + type.Name + "_" + tempInfo.Name
+ "_" + tempInfo.FieldType.Name;
SaveValue(tempInfo.GetValue(data),tempKey);
}
//进行值的获取
//tempInfo.GetValue(data);
PlayerPrefs.Save();
}
/// <summary>
/// 读取数据的类型
/// </summary>
/// <param name="type">要读取的数据类型</param>
/// <param name="name">要读取的数据名称</param>
/// <returns>返回数据实体</returns>
public object LoadData(Type type, string name)
{
//获取数据中的类型
FieldInfo[] infos = type.GetFields();
//创建存储数据信息的实体
object data = Activator.CreateInstance(type);
string tempName = null;
FieldInfo tempInfo = null;
for (int i = 0; i < infos.Length; i++)
{
tempInfo = infos[i];//数据结构中的数据名称
tempName = name + "_" + type.Name + "_" +tempInfo.Name+"_"
+tempInfo.FieldType.Name;//数据结构中的数据名称类型
//装载的容器 容器中的数据
//进行数据装载
tempInfo.SetValue(data,LoadValue(tempInfo.FieldType,tempName));
}
return data;
}
/// <summary>
/// 进行具体的类型数据的存储
/// </summary>
/// <param name="data"></param>
/// <param name="keyName"></param>
private void SaveValue(object value, string keyName)
{
Type fieldType = value.GetType();
if (fieldType == typeof(int))
{
Debug.Log("存储int"+value);
PlayerPrefs.SetInt(keyName,(int)value);
}else if (fieldType == typeof(float))
{
Debug.Log("存储float"+value);
PlayerPrefs.SetFloat(keyName,(float)value);
}else if (fieldType == typeof(string))
{
Debug.Log("存储string"+value);
PlayerPrefs.SetString(keyName,value.ToString());
}
//对于List存储的设置
//根据存储的字段类型和IList是否是父子关系
else if(typeof(IList).IsAssignableFrom(fieldType))
{
//父类装子类
IList list=value as IList;
//存储元素数量
PlayerPrefs.SetInt(keyName,list.Count);
Debug.Log("存储List长度为"+list.Count);
int index = 0;
foreach (var obj in list)
{
//存储list列表中元素内容
//命名形式是 list名字+索引编号
//递归调用存储
SaveValue(obj,keyName+index);
index++;
}
}else if (typeof(IDictionary).IsAssignableFrom(fieldType))
{
IDictionary dictionary = value as IDictionary;
//存储数据个数
PlayerPrefs.SetInt(keyName,dictionary.Count);
Debug.Log("存储Dic长度为"+dictionary.Count);
int index = 0;
foreach (var key in dictionary.Keys)
{
//存储键
SaveValue(key,keyName+"_key_"+index);
//存储值
SaveValue(dictionary[key],keyName+"_value_"+index);
index++;
}
}//自定义数据类型的存储 进行解析
else
{
SaveData(value,keyName);
}
}
private object LoadValue(Type type, string name)
{
if (type == typeof(int))
{
return PlayerPrefs.GetInt(name,0);
}else if (type == typeof(float))
{
return PlayerPrefs.GetFloat(name,0.0f);
}else if (type == typeof(string))
{
return PlayerPrefs.GetString(name,"");
}else if (typeof(IList).IsAssignableFrom(type))
{
//读取列表
int count = PlayerPrefs.GetInt(name);
IList tempList=Activator.CreateInstance(type) as IList;
for (int i = 0; i < count; i++)
{
//获取List中存储元素的类型 type.GetGenericArguments()[0]
tempList.Add(LoadValue(type.GetGenericArguments()[0],name+i));
}
return tempList;
}else if (typeof(IDictionary).IsAssignableFrom(type))
{
//进行对字典的读取
int count = PlayerPrefs.GetInt(name);
IDictionary tempDictionary=Activator.CreateInstance(type) as IDictionary;
for (int i = 0; i < count; i++)
{
tempDictionary.Add(LoadValue(type.GetGenericArguments()[0], name + "_key_" + i),
LoadValue(type.GetGenericArguments()[1], name + "_value_" + i));
}
return tempDictionary;
}
else
{
//读取自定义类成员的设置
return LoadData(type, name);
}
}
}
}