C# 如何在树中找到下一个节点?

C# 如何在树中找到下一个节点?,c#,algorithm,data-structures,graph,tree,C#,Algorithm,Data Structures,Graph,Tree,问题是这样的: 我们有一个使用类节点构建的树,其中类的实例表示树中的一个节点。为简单起见,该节点有一个int类型的数据字段。 您的任务是编写扩展方法NodeExtensions.Next()来查找树中的下一个元素。您可以根据需要编写任意多个helper方法,但不要更改扩展方法NodeExtensions.Next()的签名 我有一个节点类: public class Node { private List<Node> _children; public Node(i

问题是这样的:

我们有一个使用类节点构建的树,其中类的实例表示树中的一个节点。为简单起见,该节点有一个int类型的数据字段。 您的任务是编写扩展方法NodeExtensions.Next()来查找树中的下一个元素。您可以根据需要编写任意多个helper方法,但不要更改扩展方法NodeExtensions.Next()的签名

我有一个节点类:

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();
    }
}
我尝试的代码:

  public static Node Next(this Node node)
    {
        var newNode = NextLargerElement(node, node.Data);

        return newNode;
    }

    public static Node res;
    public static Node NextLargerElementUtil(Node root, int x) 
    {
        if (root == null)
            return null;

        if (root.Data > x)
            if ((res == null || (res).Data > root.Data))
                res = root;

        foreach (var children in root.Children)
        {
            NextLargerElementUtil(children, x);
        }

        return res;
    }

    static Node NextLargerElement(Node root, int x)
    {
        res = null;

        NextLargerElementUtil(root, x);

        return res;
 }   
下面是一个测试案例:

    [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);
    }

您可以使用
Equals
在树中回溯当前节点位置,并返回其父节点的下一个子节点(如果有),如果没有,则需要回溯当前节点父节点位置,依此类推:

public static Node Next(this Node node)
{
    if(node.Children != null && node.Children.Any())
    {
        return node.Children.First();
    }
    
    // "backtracking", also can be done recursively
    var parent = node.Parent;
    while(parent != null)
    {
        var returnNext = false; // return next element in Children if current is node
        foreach (var element in parent.Children)
        {
            if(returnNext)
            {
                return element;
            }
            
            if(element == node)
            {
                returnNext = true;
                node = parent; // to find parent's position if there is no next child
            }
        }
        parent = parent.Parent;
    }
    
    return null;
}

@鲁弗斯对不起,如果你有这样的印象,我不是故意的。我对数据结构有点迷茫。我用我尝试过的代码进行了编辑。我不会假设节点数据值已排序。Next()需要返回第一个子项或下一个兄弟项,或者继续搜索父项的兄弟项,在没有父项时停止。要找到一个兄弟姐妹,你必须跳过父母的孩子,直到你找到自己,然后把下一个孩子还给他。@GuillemSolerSuetta很乐意帮忙!
public static Node Next(this Node node)
{
    if(node.Children != null && node.Children.Any())
    {
        return node.Children.First();
    }
    
    // "backtracking", also can be done recursively
    var parent = node.Parent;
    while(parent != null)
    {
        var returnNext = false; // return next element in Children if current is node
        foreach (var element in parent.Children)
        {
            if(returnNext)
            {
                return element;
            }
            
            if(element == node)
            {
                returnNext = true;
                node = parent; // to find parent's position if there is no next child
            }
        }
        parent = parent.Parent;
    }
    
    return null;
}