拓扑排序(ABP模块排序实现)

internal class Program
{
static async Task Main(string[] args)
{
var a = new Item("A");
var c = new Item("C");
var f = new Item("F");
var h = new Item("H");
var d = new Item("D", new Item("A"));
var g = new Item("G", new Item("F"), new Item("H"));
var e = new Item("E", new Item("D", new Item("A")),
new Item("G", new Item("F"), new Item("H")));
var b = new Item("B", new Item("C"), new Item("E", new Item("D", new Item("A")),
new Item("G", new Item("F"), new Item("H"))));

var unsorted = new[] { a, b, c, d, e, f, g, h };

var sorted = TopologicalSort.Sort(unsorted, x => x.Dependencies);
Console.WriteLine(string.Join(',', sorted.Select(x => x.Name)));
Console.ReadLine();
}
}

///


/// 拓扑排序
///

public class TopologicalSort
{
public static IList Sort(
IEnumerable source,
Func<T, IEnumerable> getDependencies,
IEqualityComparer comparer = null)
{
var sorted = new List();
var visited = new Dictionary<T, bool>(comparer);

foreach (var item in source)
{
Visit(item, getDependencies, sorted, visited);
}

return sorted;
}

public static void Visit(
T item,
Func<T, IEnumerable> getDependencies,
List sorted,
Dictionary<T, bool> visited)
{
bool inProcess;
var alreadyVisited = visited.TryGetValue(item, out inProcess);

if (alreadyVisited)
{
if (inProcess)
{
throw new ArgumentException("Cyclic dependency found.");
}
}
else
{
visited[item] = true;

var dependencies = getDependencies(item);
if (dependencies != null)
{
foreach (var dependency in dependencies)
{
Visit(dependency, getDependencies, sorted, visited);
}
}

visited[item] = false;
sorted.Add(item);
}
}
}

public class Item
{
public string Name { get; private set; }
public Item[] Dependencies { get; private set; }

public Item(string name, params Item[] dependencies)
{
Name = name;
Dependencies = dependencies;
}
}

public class ItemEqualityComparer : EqualityComparer
{
public override bool Equals(Item x, Item y)
{
return (x == null && y == null) || (x != null && y != null && x.Name == y.Name);
}

public override int GetHashCode(Item obj)
{
return obj == null ? 0 : obj.Name.GetHashCode();
}
}

posted @ 2024-09-03 10:07  pojianbing  阅读(42)  评论(0)    收藏  举报