简体   繁体   English

查找树中节点的深度

[英]Find depth of node in tree

I am trying to write a function that returns the depth of a node in a non binary tree.我正在尝试编写一个 function 来返回非二叉树中节点的深度。 I've been trying for the past few hours and getting nowhere so any help would be appreciated.在过去的几个小时里,我一直在尝试,但一无所获,因此将不胜感激。 I keep getting 1 as a result.结果我一直得到1。 I am searching the tree for the exact same instances of Person.我正在树中搜索完全相同的 Person 实例。

/** 
 * Return the depth at which p occurs in this BugTree, 
 * or -1 if p is not in the BugTree.
 * Note: depth(root) is 0.
 * If p is a child of this BugTree, then depth(p) is 1. etc.
*/
public int depth(Person p) {
    if (root == p) return 0;
    if (childrenSize() == 0) return 0;
    int d= 0;
    for (BugTree c : children) {
        if (c.getRoot() == p) return 1;
        int k= c.depth(p);
        if (k != 1) {
            d= 1 + c.depth(p);
        } else {
            return d;
        }
    }

    return d;
}

Do Level Order Traversal starting from Root node.从 Root 节点开始进行 Level Order Traversal。 Let the Node have a property called depth.让节点有一个称为深度的属性。 In Level order traversal, when you add children, have their depths as parent's depth + 1. Level Order Traversal uses a Queue data structure and is pretty simple.在 Level order traversal 中,当你添加孩子时,他们的深度为 parent 的 depth + 1。 Level Order Traversal 使用 Queue 数据结构,非常简单。

        1       Level 1 or 0
      2   3     Level 2 or 1
    4  5 6  7   Level 3 or 2

Level Order Traversal: 1 2 3 4 5 6 7水平顺序遍历:1 2 3 4 5 6 7

Algorithm:算法:

LevelOrder(tree)

1) Create an empty queue q

2) temp_node = root; //with depth = 0    *start from root

3) Loop while temp_node is not NULL

    a) is temp_node the node needed? if yes print it's depth.

    b) Enqueue temp_node’s children (first left then right children) to q with child's depth = temp_node’s depth + 1

    c) Dequeue a node from q and assign it’s value to temp_node

Checkout Level Order Traversal: https://gist.github.com/yitonghe00/0b3ba3d3ad8dc008c1ebf30d0a9e8773V结帐级别订单遍历: https://gist.github.com/yitonghe00/0b3ba3d3ad8dc008c1ebf30d0a9e8773V

Using the name root for the data payload of a node is misleading.将名称root用于节点的数据有效负载会产生误导。 A sorted tree could compare, and pick the right subtree - much faster.排序树可以比较,并选择正确的子树 - 快得多。

public int depth(Person p) {
    if (data == p) { // data.equals(p)
        return 0;
    }
    for (BugTree c : children) {
        int d = c.depth(p);
        if (d != -1) {
            return 1 + d;
        }
    }
    return -1;
}

As you see it is much simpler.如您所见,它要简单得多。

I would recommend you return an Optional<Integer> rather than using an int with a special value that means 'not found'.我建议您返回Optional<Integer>而不是使用具有表示“未找到”的特殊值的int That is (IMO) clearer and less error prone.那是(IMO)更清晰,更不容易出错。 Using Java streams the solution would look like:使用 Java 流,解决方案如下所示:

public Optional<Integer> depth(Person person) {
    if (data.equals(person))
        return Optional.of(1);
    else
        return children.stream()
            .flatMap(ch -> ch.depth(person).stream())
            .findAny().map(d -> d + 1);
}

Note: I have used Optional<Integer> rather than OptionalInt to use the map method.注意:我使用Optional<Integer>而不是OptionalInt来使用map方法。 It'd certainly be possible to use OptionalInt as well but the code would be slightly more complicated.当然也可以使用OptionalInt ,但代码会稍微复杂一些。 If someone knows why the type specific variants don't have filter and map methods I'd love to hear it!如果有人知道为什么特定类型的变体没有filtermap方法,我很想听听!

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

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