如何找到树中的下一个元素

问题描述 投票:0回答:1

我有一棵树,如下图所示。

/* Tree 
*            5 
*         /    \ 
*        3      1 
*       / \    / \ 
*      2   4  6   7 
*/

我使用一个叫Node的类来创建这棵树,如下图。

var root = new Node(
            5,
            new Node(
                3,
                new Node(2),
                new Node(4)),
            new Node(
                1,
                new Node(6),
                new Node(7)));

我想打印出一个有序的树: 1 2 3 4 5 6 7...我能够找到下一个更大的元素,参考这个例子: https:/www.geeksforgeeks.orgnext-larger-element-n-ary-tree ,但我找不到如何按顺序打印所有节点。

经过编辑。

public static class Program
{
    static void Main(string[] args)
    {
        var root = new Node(
        5,
        new Node(
            3,
            new Node(2),
            new Node(4)),
        new Node(
            1,
            new Node(6),
            new Node(7)));

        var n = root;

        while (n != null)
        {
            Console.WriteLine(n.Data);
            n = n.NextNode();
        }
    }

    public static Node NextNode(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;
    }
}

还有... Node 类。

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();
    }
}
c# .net .net-core tree console-application
1个回答
1
投票

你需要一个 递归 迭代器 函数来遍历所有的分支并得到所有的节点。

public IEnumerable<Node> GetAllNodes(Node parent)               
{
    IEnumerable<Node> GetAllNodes(IEnumerable<Node> children)
    {
        foreach(var child in children)
        {
            yield return child;
            foreach(var c in GetAllNodes(child.Children))
                yield return c;
        }
    }

    yield return parent;

    foreach(var child in GetAllNodes(parent.Children))
        yield return child;
}

如果你有一棵树,比如:

var root = new Node(5,
    new Node(3, new Node(11), new Node(12),
    new Node(2),
    new Node(4), new Node(13)),
    new Node(1, new Node(14), new Node(15),
    new Node(6, new Node(16), new Node(17)),
    new Node(7, new Node(8), new Node(9))), new Node(10));

调用这个函数,传递 root 节点,而OrderBy Data 属性。

var q = GetAllNodes(root).OrderBy(x => x.Data).Select(x => x.Data);

Console.WriteLine(string.Join(", ", q));

输出是:

1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17

最好把它变成一个 扩展方法 对于 Node 型。

static class Extensions
{
    public static IEnumerable<Node> GetAllNodes(this Node parent)
    {
        IEnumerable<Node> GetAllNodes(IEnumerable<Node> children)
        {
            foreach (var child in children)
            {
                yield return child;
                foreach (var c in GetAllNodes(child.Children))
                    yield return c;
            }
        }

        yield return parent;

        foreach (var child in GetAllNodes(parent.Children))
            yield return child;
    }
}

所以你可以这样称呼它。

var q = root.GetAllNodes().OrderBy(x => x.Data).Select(x => x.Data);

Console.WriteLine(string.Join(", ", q));
© www.soinside.com 2019 - 2024. All rights reserved.