[Breadth traversal and depth traversal] talking about algorithms, design patterns, and breadth design patterns

Source: Internet
Author: User

[Breadth traversal and depth traversal] talking about algorithms, design patterns, and breadth design patterns

In the evening, I was bored with writing a binary tree (graph)'s breadth and depth traversal algorithm. The algorithm itself is very simple, but how can it be universal? The code below is my design, please help me to see if there are any problems. I feel that there is a problem, that is, I don't know what the problem is.

    public interface IGraph<TVertex>    {        IEnumerable<IEdge<TVertex>> Edges { get; }    }
    public interface IEdge<TVertex>    {        TVertex From { get; set; }        TVertex To { get; set; }    }
    public interface INode    {        IEnumerable<TNode> GetNextNodes<TNode>() where TNode : INode;    }
    public class Edge<TVertex> : IEdge<TVertex>    {        public TVertex From { get; set; }        public TVertex To { get; set; }    }
    public static class NodeVisitor    {        public static void BreadthVisit<TNode>(TNode rootNode, Action<TNode> visitAction)           where TNode : INode        {            BreadthVisit(rootNode, n => n.GetNextNodes<TNode>(), visitAction);        }        public static void BreadthVisit<TNode>(TNode rootNode, Func<TNode,IEnumerable<TNode>> nextNodeSelector, Action<TNode> visitAction)        {            var nodeQueue = new Queue<TNode>();            nodeQueue.Enqueue(rootNode);            while (nodeQueue.Any())            {                var currentNode = nodeQueue.Dequeue();                if (visitAction != null)                {                    visitAction(currentNode);                }                foreach (var nextNode in nextNodeSelector(currentNode))                {                    nodeQueue.Enqueue(nextNode);                }            }        }        public static void DepthVisit<TNode>(TNode rootNode, Func<TNode, IEnumerable<TNode>> nextNodeSelector, Action<TNode> visitAction)        {            var nodeStack = new Stack<TNode>();            nodeStack.Push(rootNode);            while (nodeStack.Any())            {                var currentNode = nodeStack.Pop();                if (visitAction != null)                {                    visitAction(currentNode);                }                foreach (var nextNode in nextNodeSeletor(currentNode))                {                    nodeStack.Push(nextNode);                }            }        }        public static void DepthVisit<TNode>(TNode rootNode, Action<TNode> visitAction)           where TNode : INode        {            DepthVisit(rootNode, n => n.GetNextNodes<TNode>(), visitAction);        }    }
    public class GraphVisitor<TVertex>     {        private IGraph<TVertex> _graph;        public GraphVisitor(IGraph<TVertex> graph)        {            _graph = graph;        }        public TVertex GetRoot()        {            var vertexs = _graph.Edges.Select(t => t.From).Concat(_graph.Edges.Select(t => t.To));            var toVertexs = _graph.Edges.Select(t => t.To);            return vertexs.FirstOrDefault(t => toVertexs.All(v => !v.Equals(t)));        }        public IEnumerable<TVertex> GetNextVertexs(TVertex current)        {            return _graph.Edges.Where(t => t.From.Equals(current)).Select(t => t.To);        }        public void BreadthVisit(Action<TVertex> visitAction, TVertex startVertex)        {            NodeVisitor.BreadthVisit(startVertex, t => GetNextVertexs(t), visitAction);        }        public void BreadthVisit(Action<TVertex> visitAction)        {            NodeVisitor.BreadthVisit(GetRoot(), t => GetNextVertexs(t), visitAction);        }        public void DepthVisit(Action<TVertex> visitAction, TVertex startVertex)        {            NodeVisitor.DepthVisit(startVertex, t => GetNextVertexs(t), visitAction);        }        public void DepthVisit(Action<TVertex> visitAction)        {            NodeVisitor.DepthVisit(GetRoot(), t => GetNextVertexs(t), visitAction);        }        private class GraphNode : INode        {            private IList<INode> nodes = new List<INode>();            public string Id { get; set; }            public void AddNext(INode node)            {                nodes.Add(node);            }            public IEnumerable<TNode> GetNextNodes<TNode>() where TNode : INode            {                return nodes.Cast<TNode>();            }        }    }

 Unit test code:

[TestClass] public class BreadthVisitorTest {[TestMethod] public void TestVisit () {var node1 = new TestNode () {Id = "1"}; var node1_1 = new TestNode () {Id = "1_1"}; var node1_2 = new TestNode () {Id = "1_2"}; var node1_1_1 = new TestNode () {Id = "1_1_1 "}; var node1_1_2 = new TestNode () {Id = "1_1_2"}; var node1_1_3 = new TestNode () {Id = "1_1_3"}; var node1_2_1 = new TestNode () {Id = "1_2_1"}; var node1_2_2 = new TestNode () {Id = "1_2_2"}; node1.AddNext (node1_1); node1.AddNext (node1_2); node1_1.AddNext (node1_1_1 ); partition (node1_1_2); node1_1.AddNext (node1_1_3); node1_2.AddNext (node1_2_1); node1_2.AddNext (node1_2_2); var expected = "1.1 _ 1.1 _ 2.1 _ partition"; var actual = ""; nodeVisitor. breadthVisit (node1, n => {actual + = n. id + ". ";}); Assert. areEqual (expected, actual. trim ('. '); expected = "1.1 _ 1.1 _ 00001.000000002.000000003.00002.1_2_1.1_2_2"; actual = ""; NodeVisitor. depthVisit (node1, n => {actual + = n. id + ". ";}) ;}[ TestMethod] public void TestGraphVisit () {var graph = new Graph (); var graphVisitor = new GraphVisitor <int> (graph); graph. addEdge (1, 2); graph. addEdge (1, 3); graph. addEdge (2, 4); graph. addEdge (2, 5); graph. addEdge (3, 6); var expected = "123456"; var actual = ""; graphVisitor. breadthVisit (a ==>{ actual + =. toString () ;}); Assert. areEqual (expected, actual); expected = "124536"; actual = ""; graphVisitor. depthVisit (a ==>{ actual + =. toString () ;}) ;}} public class TestNode: INode {private IList <INode> nodes = new List <INode> (); public string Id {get; set ;} public void AddNext (INode node) {nodes. add (node);} public IEnumerable <TNode> GetNextNodes <TNode> () where TNode: INode {return nodes. cast <TNode> () ;}} public class Graph: IGraph <int> {private IList <IEdge <int> _ edges = new List <IEdge <int> (); public IEnumerable <IEdge <int> Edges {get {return _ edges;} public void AddEdge (int from, int to) {_ edges. add (new Edge <int> () {From = from, To = });}}View Code

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.