Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/364.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在树中查找节点的深度_Java_Recursion_Tree - Fatal编程技术网

Java 在树中查找节点的深度

Java 在树中查找节点的深度,java,recursion,tree,Java,Recursion,Tree,我试图编写一个函数,返回非二叉树中节点的深度。在过去的几个小时里,我一直在努力,但一事无成,所以如果有任何帮助,我将不胜感激。结果我一直得1分。我在树上搜索完全相同的人的实例 /** * 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, t

我试图编写一个函数,返回非二叉树中节点的深度。在过去的几个小时里,我一直在努力,但一事无成,所以如果有任何帮助,我将不胜感激。结果我一直得1分。我在树上搜索完全相同的人的实例

/** 
 * 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;
}

从根节点开始执行级别顺序遍历。让节点具有名为depth的属性。在级别顺序遍历中,添加子级时,将其深度作为父级的深度+1。级别顺序遍历使用队列数据结构,非常简单

        1       Level 1 or 0
      2   3     Level 2 or 1
    4  5 6  7   Level 3 or 2
级别顺序遍历:1234567

算法:

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

签出级别顺序遍历:

为节点的数据有效负载使用名称
root
,这会产生误导。 排序后的树可以进行比较,并选择正确的子树——速度要快得多

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

正如您所看到的,它要简单得多。

我建议您返回一个
可选的
,而不是使用带有表示“未找到”的特殊值的
int
。这(在国际海事组织)更清晰,更不容易出错。使用Java streams,解决方案如下所示:

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);
}
公共可选深度(个人){
if(数据等于(人))
返回可选。共(1);
其他的
返回children.stream()
.flatMap(ch->ch.depth(person.stream())
.findAny().map(d->d+1);
}

注意:我使用了
Optional
而不是
OptionalInt
来使用
map
方法。当然也可以使用
optionant
,但代码会稍微复杂一些。如果有人知道为什么特定类型的变体没有
filter
map
方法,我很想听听

除非您使用存储在树中的完全相同的Person实例搜索树(请编辑您的问题以澄清),否则此条件
if(root==p)
将不适用于您。最好在
Person
中实现
equals()
,并使用
if(root.equals(p))
。您可能还需要对
根目录进行空检查。另外,名字
root
可疑-是否
root
真的属于
Person
类型?另外,您的方法看起来不够递归。我正在树中搜索与Person完全相同的实例。我将编辑澄清,谢谢。