简体   繁体   English

找到树的最大深度

[英]Find the maximum depth of a tree

I have a tree data structure with N first-level child nodes that have childs too. 我有一个树数据结构,其中N个第一级子节点也有子节点。

For example: 例如:

  • Root
    • Node1 节点1
      • Node11 Node11
        • Node111 Node111
          • Node1111 Node1111
      • Node12 Node12
    • Node2 节点2
      • Node21 Node21
        • Node211 Node211

I would like to know which of the braches has the biggest depth. 我想知道哪个分支最深。 As in the previous example it will be 如前面的例子所示

Node1 - Node11 - Node111 - Node1111 节点1 - 节点11-节点111-节点1111

that has a depth of four levels. 具有四个级别的深度。

Any suggestion? 有什么建议吗?

Thanks! 谢谢!

You must check all nodes. 您必须检查所有节点。 Several months ago I implemented this algorithm in this way: 几个月前,我用这种方式实现了这个算法:

class Node
{
    public String Name { get; private set; }
    public IList<Node> Childs { get; private set; }

    public Node(String name)
    {
        Name = name;
        Childs = new List<Node>();
    }

    public List<Node> Depth
    {
        get
        {
            List<Node> path = new List<Node>();
            foreach (Node node in Childs)
            {
                List<Node> tmp = node.Depth;
                if (tmp.Count > path.Count)
                    path = tmp;
            }
            path.Insert(0, this);
            return path;
        }
    }

    public override string ToString()
    {
        return Name;
    }
}

Example test: 示例测试:

Node node1111 = new Node("Node1111");
Node node111 = new Node("Node111");
Node node11 = new Node("Node11");
Node node12 = new Node("Node12");
Node node1 = new Node("Node1");
Node root = new Node("Root");
Node node2 = new Node("Node2");
Node node21 = new Node("Node21");
Node node211 = new Node("Node211");
root.Childs.Add(node1);
root.Childs.Add(node2);
node1.Childs.Add(node11);
node1.Childs.Add(node12);
node11.Childs.Add(node111);
node111.Childs.Add(node1111);
node2.Childs.Add(node21);
node21.Childs.Add(node211);

List<Node> path = root.Depth;
foreach (Node n in path)
    Console.Write(String.Format("{0} - ", n.ToString()));

Console.WriteLine();

Node node2111 = new Node("Node2111");
node2111.Childs.Add(new Node("Node21111"));
node211.Childs.Add(node2111);

path = root.Depth;
foreach (Node n in path)
    Console.Write(String.Format("{0} - ", n.ToString()));

Console.WriteLine();

Console output: 控制台输出:

Root - Node1 - Node11 - Node111 - Node1111 -
Root - Node2 - Node21 - Node211 - Node2111 - Node21111 -

The most straightforward is a brute force algorithm which enumerates every path, saves pointers to all the nodes, and measures the depth. 最直接的是一种强力算法,它枚举每个路径,保存指向所有节点的指针,并测量深度。 For each path which is longer than a previous path, forget all other paths and only remember the longest. 对于比前一个路径长的每个路径,忘记所有其他路径并且只记住最长的路径。

The deepest branch from a node is:
    the longest of the respective deepest branches from each child node
    prepended with the current node.

Traverse the tree depth-first or breadth-first, assigning to each node its depth. 遍历树深度优先或广度优先,为每个节点分配其深度。 Remember the node with the highest depth. 记住深度最高的节点。

Navigate recusrivle back from that node to the root. 导航从该节点返回到根节点。 This gives you the lngest branch. 这为您提供了最年轻的分支。 There might be more than one branch with the same length. 可能有多个分支具有相同的长度。

If you have any form of iterator over your tree then you can use a perfectly mundane approach to the max depth. 如果您的树上有任何形式的迭代器,那么您可以使用完全平凡的方法来获得最大深度。

Here's silly one-liner showing the concept for finding maximum reachable filesystem depth using UNIX find , awk and tr : 这是一个愚蠢的单行显示使用UNIX findawktr查找最大可达文件系统深度的概念:

find / -depth | tr -dc '/\n' \
    | awk '{if (length($0) > max) { max=length($0)}}; END {print max}'

... find is the iterator, tr is a data manipulation "translating" one set of characters into another (in this case it's being used to -d (delete) the complement (-c) of the single character set being specified (/). So it converts any UNIX full path into just the / separators. From there I just find the longest line of input ... and that's my result. ... find是迭代器, tr是一个数据操作“将一组字符”翻译成另一组(在这种情况下,它被用于-d(删除)指定的单个字符集的补充(-c)(/因此,它将任何UNIX完整路径转换为/ separators。从那里我只找到最长的输入行......这就是我的结果。

Of course this approach won't help you much with your homework assignment. 当然,这种方法对你的家庭作业没什么帮助。 But the concept should be clear. 但这个概念应该是清楚的。 :) :)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM