Performing Breadth First Search recursively

后端 未结 21 2594
不思量自难忘°
不思量自难忘° 2020-11-28 01:12

Let\'s say you wanted to implement a breadth-first search of a binary tree recursively. How would you go about it?

Is it possible using only the call-stack

21条回答
  •  鱼传尺愫
    2020-11-28 01:53

    C# implementation of recursive breadth-first search algorithm for a binary tree.

    Binary tree data visualization

    IDictionary graph = new Dictionary {
        {"A", new [] {"B", "C"}},
        {"B", new [] {"D", "E"}},
        {"C", new [] {"F", "G"}},
        {"E", new [] {"H"}}
    };
    
    void Main()
    {
        var pathFound = BreadthFirstSearch("A", "H", new string[0]);
        Console.WriteLine(pathFound); // [A, B, E, H]
    
        var pathNotFound = BreadthFirstSearch("A", "Z", new string[0]);
        Console.WriteLine(pathNotFound); // []
    }
    
    IEnumerable BreadthFirstSearch(string start, string end, IEnumerable path)
    {
        if (start == end)
        {
            return path.Concat(new[] { end });
        }
    
        if (!graph.ContainsKey(start)) { return new string[0]; }    
    
        return graph[start].SelectMany(letter => BreadthFirstSearch(letter, end, path.Concat(new[] { start })));
    }
    

    If you want algorithm to work not only with binary-tree but with graphs what can have two and more nodes that points to same another node you must to avoid self-cycling by holding list of already visited nodes. Implementation may be looks like this.

    Graph data visualization

    IDictionary graph = new Dictionary {
        {"A", new [] {"B", "C"}},
        {"B", new [] {"D", "E"}},
        {"C", new [] {"F", "G", "E"}},
        {"E", new [] {"H"}}
    };
    
    void Main()
    {
        var pathFound = BreadthFirstSearch("A", "H", new string[0], new List());
        Console.WriteLine(pathFound); // [A, B, E, H]
    
        var pathNotFound = BreadthFirstSearch("A", "Z", new string[0], new List());
        Console.WriteLine(pathNotFound); // []
    }
    
    IEnumerable BreadthFirstSearch(string start, string end, IEnumerable path, IList visited)
    {
        if (start == end)
        {
            return path.Concat(new[] { end });
        }
    
        if (!graph.ContainsKey(start)) { return new string[0]; }
    
    
        return graph[start].Aggregate(new string[0], (acc, letter) =>
        {
            if (visited.Contains(letter))
            {
                return acc;
            }
    
            visited.Add(letter);
    
            var result = BreadthFirstSearch(letter, end, path.Concat(new[] { start }), visited);
            return acc.Concat(result).ToArray();
        });
    }
    

提交回复
热议问题