无法搜索C#中的所有树节点

Unable to search all the tree nodes in C#

我有一棵使用 class 节点构建的树,其中 class 的实例代表树中的一个节点。为简单起见,该节点有一个 int 类型的数据字段。

扩展方法 NodeExtensions.Next() 在树中查找下一个元素。您可以根据需要编写任意数量的辅助方法,但不要更改扩展方法的签名 NodeExtensions.Next().

我无法回到节点2再移动到子节点3,请帮我算法。

节点 class 看起来像这样:

public class Node
{
    private List<Node> _children;

    public Node(int data, params Node[] nodes)
    {
        Data = data;
        AddRange(nodes);
    }

    public Node Parent { get; set; }

    public IEnumerable<Node> Children
    {
        get
        {
            return _children != null
                ? _children
                : Enumerable.Empty<Node>();
        }
    }

    public int Data { get; private set; }

    public void Add(Node node)
    {
        Debug.Assert(node.Parent == null);

        if (_children == null)
        {
            _children = new List<Node>();
        }

        _children.Add(node);
        node.Parent = this;
    }

    public void AddRange(IEnumerable<Node> nodes)
    {
        foreach (var node in nodes)
        {
            Add(node);
        }
    }

    public override string ToString()
    {
        return Data.ToString();
    }
}

测试方法

[Test]
    public void Test()
    {
        // Test tree:
        // 
        // 1
        // +-2
        //   +-3
        //   +-4
        // +-5
        //   +-6
        //   +-7
        //
        var root = new Node(
            1,
            new Node(
                2,
                new Node(3),
                new Node(4)),
            new Node(
                5,
                new Node(6),
                new Node(7)));

        // Expected output:
        //
        // 1
        // 2
        // 3
        // 4
        // 5
        // 6
        // 7
        //
        var n = root;
        while (n != null)
        {
            Console.WriteLine(n.Data);
            n = n.Next();
        }

        // Test
        //
        n = root;
        Assert.AreEqual(1, n.Data);
        n = n.Next();
        Assert.AreEqual(2, n.Data);
        n = n.Next();
        Assert.AreEqual(3, n.Data);
        n = n.Next();
        Assert.AreEqual(4, n.Data);
        n = n.Next();
        Assert.AreEqual(5, n.Data);
        n = n.Next();
        Assert.AreEqual(6, n.Data);
        n = n.Next();
        Assert.AreEqual(7, n.Data);
        n = n.Next();
        Assert.IsNull(n);
    }

我的代码

public static Node Next(this Node node)
    {
    
        if(node != null && node.Children != null && node.Children.Count() > 0)
        {
            for(int i = 0; i < node.Children.Count(); i++)
            {
               foreach(var child in node.Children)
               {
                 child.Next();
                 return child;
               }
            }
        }
        else{
            return null;
        }
   
    }

我的代码输出
1
2
3

预期输出应该是

1
2
3
4
5
6
7

这有效并通过了您的测试。我假设您无法更改 Node class.

public static Node Next(this Node node)
    {
        if (node.Children.Any())
            return node.Children.First();

        var parent = node.Parent;
        while (parent != null)
        {
            var nextNode = parent.Children.FindChildAfter(node);
            if (nextNode == null)
            {
                node = parent;
                parent = parent.Parent;
            }
            else
                return nextNode;
        }

        return null;
    }

    public static Node FindChildAfter(this IEnumerable<Node> items, Node item)
    {
        bool found = false;
        foreach (var it in items)
        {
            if (found) return it;
            if (ReferenceEquals(it, item)) 
                found = true;
        }

        return null;
    }

FindChildAfter 效率低下,因为它每次都必须遍历整个集合。会有更好的方法来构建它,所以情况并非如此。

作为替代方法,您可以考虑让 Node 实施 IEnumerable<Node>。如果你这样做那么你只需要实现这两个方法:

public IEnumerator<Node> GetEnumerator()
{
    yield return this;
    foreach (var child in Children)
        foreach (var x in child)
            yield return x;
}

IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();

现在遍历您的节点很简单了:

var data = root.Select(x => x.Data).ToArray();

这给了我一个 1, 2, 3, 4, 5, 6, 7 的数组。