拓扑排序

来源:互联网 发布:吴昕的淘宝店铺网址 编辑:程序博客网 时间:2024/05/18 04:50
<pre name="code" class="csharp">using System;using System.Collections.Generic;using System.Linq;namespace ConsoleApplication1 {
<pre style="margin-top: 0px; margin-bottom: 0px; padding: 0px; white-space: pre-wrap; word-wrap: break-word; line-height: 21px; font-family: 'Courier New' !important;"><span style="margin: 0px; padding: 0px; line-height: 1.5 !important;"></span><pre name="code" class="csharp">        class Program {            static void Main(string[] args)
            {              List<TopologicNode> nodes = new List<TopologicNode>()              {                new TopologicNode(){ Key = "XMedia",                     Dependences = new List<string>(){ "XMedia.Controllers", "XMedia.Models", "XMedia.Logics", "XMedia.Commons" } },                new TopologicNode(){ Key = "XMedia.Controllers",                    Dependences = new List<string>(){"XMedia.Models","XMedia.Logics","XMedia.Commons"}},                new TopologicNode(){ Key = "XMedia.Logics",                     Dependences = new List<string>(){ "XMedia.Models","XMedia.Commons"}},                new TopologicNode(){ Key = "XMedia.Models" },                new TopologicNode(){ Key = "XMedia.Commons" }             };             //输出拓扑排序的结果            TopologicSort sort = new TopologicSort();            foreach (var key in sort.OrderBy(nodes)) {                Console.WriteLine(key);            }            Console.ReadLine();         }    }
/// <summary> /// 拓扑排序类。 /// </summary> public class TopologicSort { /// <summary> /// 拓扑顺序。 /// </summary> /// <typeparam name="TKey">节点的键值类型。</typeparam> /// <param name="nodes">一组节点。</param> /// <returns>拓扑序列。</returns> /// <exception cref="InvalidOperationException">如果存在双向引用或循环引用,则抛出该异常。</exception> public IEnumerable<string> OrderBy(IEnumerable<TopologicNode> nodes) { if (nodes == null) yield break; //复制一份,便于操作 List<TopologicNode> list = new List<TopologicNode>(); foreach (var item in nodes) { TopologicNode node = new TopologicNode() { Key = item.Key }; if (item.Dependences != null) node.Dependences = new List<string>(item.Dependences); list.Add(node); } while (list.Count > 0) { //查找依赖项为空的节点 var item = list.FirstOrDefault(c => c.Dependences == null || c.Dependences.Count == 0); if (item != null) { yield return item.Key; //移除用过的节点,以及与其相关的依赖关系 list.Remove(item); foreach (var otherNode in list) { if (otherNode.Dependences != null) otherNode.Dependences.Remove(item.Key); } } else if (list.Count > 0) { //如果发现有向环,则抛出异常 throw new InvalidOperationException("存在双向引用或循环引用。"); } } } } /// <summary> /// 拓扑节点类。 /// </summary> public class TopologicNode { /// <summary> /// 获取或设置节点的键值。 /// </summary> public string Key { get; set; } /// <summary> /// 获取或设置依赖节点的键值列表。 /// </summary> public List<string> Dependences { get; set; } }}



0 0
原创粉丝点击