mirror of https://github.com/ErsatzTV/ErsatzTV.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
47 lines
1.2 KiB
47 lines
1.2 KiB
namespace ErsatzTV.Core.Search; |
|
|
|
public class AdjGraph |
|
{ |
|
private readonly List<Edge> _edges = []; |
|
|
|
public void Clear() => _edges.Clear(); |
|
|
|
public void AddEdge(string from, string to) => _edges.Add(new Edge(from.ToLowerInvariant(), to.ToLowerInvariant())); |
|
|
|
public bool HasCycle(string from) |
|
{ |
|
var visited = new System.Collections.Generic.HashSet<string>(); |
|
var stack = new System.Collections.Generic.HashSet<string>(); |
|
return HasCycleImpl(from.ToLowerInvariant(), visited, stack); |
|
} |
|
|
|
public bool HasAnyCycle() => _edges.Any(edge => HasCycle(edge.From)); |
|
|
|
private bool HasCycleImpl(string node, ISet<string> visited, ISet<string> stack) |
|
{ |
|
if (stack.Contains(node)) |
|
{ |
|
return true; |
|
} |
|
|
|
if (!visited.Add(node)) |
|
{ |
|
return false; |
|
} |
|
|
|
stack.Add(node); |
|
|
|
foreach (Edge edge in _edges.Where(e => e.From == node)) |
|
{ |
|
if (HasCycleImpl(edge.To, visited, stack)) |
|
{ |
|
return true; |
|
} |
|
} |
|
|
|
stack.Remove(node); |
|
return false; |
|
} |
|
|
|
private record Edge(string From, string To); |
|
}
|
|
|