ToopoLogical Sort (拓扑排序)

来源:互联网 发布:99热网址最新获取域名 编辑:程序博客网 时间:2024/06/16 03:10
ToopoLOgical Sort 


Target :
Sort the nodes in graph ,to find out the graph have cycle or not .
result nodes only contains the nodes have not "involed in the cycle"


steps :
0.prepare node list to save result nodes


1.get all nodes in graph
2.find out the nodes not have a incoming edge ,save to tempNodes
3.foreach the tempNodes , add to result ,then remove .
4.recurs .


sample codes :


 
 public class ToopoNode    {        public string NodeValue;        public int NodeId;        public List<ToopoNode> TargetNodes;    }    public class ToopoSort    {        private List<ToopoNode> _resultNodes;         public ToopoSort()        {            _resultNodes = new List<ToopoNode>();        }        public List<ToopoNode> GetSortedList(List<ToopoNode> nodes)        {            GetSortedNode(nodes);            return _resultNodes;        }        private void GetSortedNode(List<ToopoNode> nodes)        {            if (nodes.Count == 0)                return;            //step 1 : get all target nodes            var targetList = new List<ToopoNode>();            foreach (var node in nodes)            {                foreach (var n in node.TargetNodes)                {                    if (!targetList.Contains(n))                        targetList.Add(n);                }            }            var noHaveInCommingEdgeNodes = nodes.Where(node => !targetList.Contains(node)).ToList();            if (noHaveInCommingEdgeNodes.Count == 0)                return;            //step 2: add not-have-target nodes into result            foreach (ToopoNode n in noHaveInCommingEdgeNodes)            {                if(!_resultNodes.Contains(n))                _resultNodes.Add(n);                nodes.Remove(n);            }            //step 3:recurs            GetSortedNode(nodes);        }    }




Unit- Test :


 [TestMethod]        public void ToopoSort()        {//create nodes            var node1 = new ToopoNode() { NodeId = 1, TargetNodes = new List<ToopoNode>() };            var node2 = new ToopoNode() { NodeId = 2, TargetNodes = new List<ToopoNode>() };            var node3 = new ToopoNode() { NodeId = 3, TargetNodes = new List<ToopoNode>() };            var node4 = new ToopoNode() { NodeId = 4, TargetNodes = new List<ToopoNode>() };            var node5 = new ToopoNode() { NodeId = 5, TargetNodes = new List<ToopoNode>() };            var node6 = new ToopoNode() { NodeId = 6, TargetNodes = new List<ToopoNode>() };            var node7 = new ToopoNode() { NodeId = 7, TargetNodes = new List<ToopoNode>() };            var node8 = new ToopoNode() { NodeId = 8, TargetNodes = new List<ToopoNode>() };            var node9 = new ToopoNode() { NodeId = 9, TargetNodes = new List<ToopoNode>() };            var node10 = new ToopoNode() { NodeId = 10, TargetNodes = new List<ToopoNode>() };            var node11 = new ToopoNode() { NodeId = 11, TargetNodes = new List<ToopoNode>() };//setup relations between nodes            node1.TargetNodes.Add(node2);            node2.TargetNodes.Add(node3);            node2.TargetNodes.Add(node4);            node2.TargetNodes.Add(node5);            //node3.TargetNodes.Add(node10);            node3.TargetNodes.Add(node11);            node4.TargetNodes.Add(node5);            node4.TargetNodes.Add(node11);            node5.TargetNodes.Add(node6);            node5.TargetNodes.Add(node7);            node5.TargetNodes.Add(node8);            node6.TargetNodes.Add(node9);            node10.TargetNodes.Add(node3);            node11.TargetNodes.Add(node10);            var nodeList = new List<ToopoNode>()                {                    node1,                    node2,                    node3,                    node4,                    node5,                    node6,                    node7,                    node8,                    node9,                    node10,                    node11                };//toopoSort ,find out if have a cycle or not //cycle nodes can not be in result nodes            var ret = new ToopoSort().GetSortedList(nodeList);            var retStr = "";            foreach (var n in ret)            {                retStr += n.NodeId + ",";            }        }