c# - 在这种情况下如何检查链表是否有循环
问题描述
必须创建一个链接列表,我们将在其中添加相互依赖或不依赖的部门。
输入将是部门名称,后跟它们所依赖的部门名称,有些可以后跟空字符串,这意味着它们不依赖于任何部门。
所以输出将首先是第二个部门,依此类推
一个部门不能靠自己(小心)
必须查找部门是否具有循环依赖(问题)
输入
销售量
营销账户
财务销售
所以输出将是
销售财务账户营销
输入
销售与市场营销
营销账户
账户销售
输出
错误它不能有循环依赖
尝试使用以下代码查看我的链接列表是否有循环
private bool DoesItHasLoops()
{
var fast = myLinkedList.First;
var slow = myLinkedList.First;
while (fast != null && fast.Next != null)
{
fast = fast.Next.Next;
slow = slow.Next;
if (slow == fast)
return true;
}
return false;
}
它不工作,无法找到循环。
下面的代码是我在链表中添加字符串的方式。
private LinkedList<strings> myLinkedList;
public void AddDepartments(string[] input)
{
if (input.Count() > 1)
{
if (myLinkedList.Contains(input[0]))
{
myLinkedList.AddBefore(adjList.Find(input[0]), input[1]);
}
else
{
myLinkedList.AddLast(input[1]);
myLinkedList.AddLast(input[0]);
}
}
else
{
myLinkedList.AddLast(input[0]);
myLinkedList.AddLast(string.empty());
}
}
这适用于所有情况,只有循环情况它不起作用
解决方案
在我看来,识别这些循环的最简单方法是找到那些具有依赖关系的部门在某个时候也被列为依赖关系本身的那些,并遍历它们之间的依赖关系链以查看它们是否连接。也就是说,您的架构似乎有点不对劲。我将创建一个对象来保存该部门及其依赖项列表以及一个标志,以确定它是否具有这样的循环引用:
public class Department
{
public int Id { get; set; }
public string Name { get; set; }
public IList<int> Dependencies { get; set; }
public bool HasCircularReferences { get; set; }
}
然后,您传入一个部门列表并遍历每个部门,并找到将该部门列为依赖项的其他部门。然后,您通过依赖链从这些方面进行工作,以查看您是否最终回到当前部门。您可以使用这样的循环(请注意,这是一个静态方法,因为我在控制台应用程序中对其进行了测试):
private static void GetDependents(IList<int> dependencies, int seed)
{
foreach (var dependent in dependencies)
{
var dependentDept = departments.Where(d => d.Id == dependent).FirstOrDefault();
if (dependentDept.Dependencies.Count > 0)
{
if (dependencies.Contains(seed) || dependentDept.HasCircularReferences)
{
SetCircularReferenceFlag(seed, true);
break;
}
GetDependents(dependentDept.Dependencies, seed);
}
else
{
SetCircularReferenceFlag(seed, false);
break;
}
}
}
这使用 SetCircularReferenceFlag 方法在部门上设置 HasCircularReferences 标志,该方法是:
private static void SetCircularReferenceFlag(int departmentId, bool hasCircularReferences)
{
var seedDept = departments.Where(d => d.Id == departmentId).FirstOrDefault();
seedDept.HasCircularReferences = hasCircularReferences;
}
然后可以为列表中的每个部门调用 GetDependents 方法,如下所示:
foreach (var department in departments)
{
GetDependents(department.Dependencies, department.Id);
}
使用上面定义的 Department 对象,已将 Departments 设置为如下所示:
private static List<Department> departments = new List<Department>
{
new Department
{
Id = 1,
Name = "sales",
Dependencies = new List<int>{ 2 }
},
new Department
{
Id = 2,
Name = "accounts",
Dependencies = new List<int>{ 3 }
},
new Department
{
Id = 3,
Name = "marketing",
Dependencies = new List<int>{ 1 }
},
new Department
{
Id = 4,
Name = "finance",
Dependencies = new List<int>{ 1 }
}
};
通过控制台应用程序运行它时,您会得到以下结果:
推荐阅读
- javascript - 当页面内容通过 jQuery ajax 调用响应在 DOM 上呈现时,在视图上呈现脚本部分
- go - 关于主程序和子程序同时收听同一频道的问题
- reactjs - VSCode 上的 Eslint 和 Prettier 将我的 JSX 代码上的任何空间更改为 React Native 项目中的 {' '}
- r - 加速时间间隔过滤 - R
- r - 添加按同一列分组的另一列的前一行值(足球数据)
- python - 广义骰子损失问题
- sql - SQLite:按每个日期分组的两个日期之间的差异总和
- c# - 负前瞻行为不符合预期
- java - 三元运算符中不需要的 NullPointerException - 为什么?
- java - 通信链路故障(MYSQL SERVER 8 + JAVA)