拓扑排序(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();
    }
}

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

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

        return sorted;
    }

    public static void Visit<T>(
        T item, 
        Func<T, IEnumerable<T>> getDependencies,
        List<T> 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<Item>
{
    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  阅读(6)  评论(0编辑  收藏  举报