如何在树Java中查找节点

时间:2018-08-13 22:49:29

标签: java tree

我是Java的初学者,目前正在尝试解决“树”一章中的练习。

一棵树由这些节点组成。 enter image description here。节点拥有一个对应于整数的值。 除了树根上的节点外,一个节点始终只有另一个引用它的节点。 如果节点的右侧或左侧没有子代,则相应的引用为null。 左侧子树中任何子项所拥有的价值小于其父项的价值,右侧子树中任何子项所拥有的价值均大于其父项的价值。 树的高度在0到10万节之间。

我正在尝试实现一种find(int v)方法,该方法返回持有值v的节点,如果该节点不存在,那么find将必须返回null

这是我所做的,直到知道,但我有点迷茫:

class Node{
    Node left, right;
    int value;

    public Node find (int v){
        Node result = null;
        if (this.left != null) result = find(v);
        if (this.value == v) return this;
        if (result == null && this.right != null) 
            result = find(v);

        return result;     

    }

    public static void main (String[] args){
        Node n = smallNode.find(8);
        System.out.println(n);
        n = LargestNode.find(0);
        System.out.println(n);
    }
}

我在这一行得到StackoverOverflowError

if (this.left != null) result = find(v);

我在做什么错?我找不到为什么会引发这种异常。

4 个答案:

答案 0 :(得分:2)

您应该首先检查该值,如果节点具有您要查找的值,则返回this。如果未选中,则可以从当前节点继续并向右移动,一旦返回,请检查具有给定值的结果,如果正确,则返回该Node,否则返回左侧给出的值。它将是具有所需值的Node或为null。

public Node find (int v){
    Node result = null;

    //check for value first
    if (this.value == v) return this;

    //check if you can go any further from the current node
    if(this.left == null && this.right == null) return null;

    //now go right
    result = this.right.find(v);

    //check the node
    if(result != null && result.value == v) return result;

    //if not found return whatever is returned by searching left
    return this.left.find(v);
}

答案 1 :(得分:1)

您的find方法不断使用接收到的相同参数进行调用。因此,您实际上并没有遍历任何节点。相反,您会一次又一次地检查同一节点。

由于find不断不断地自我调用,因此在某个时刻调用堆栈用完了。这就是为什么您得到StackOverflowError

尝试使用调试器逐步完成find,但这并没有达到您的预期。

答案 2 :(得分:1)

解决步骤

  1. 如果搜索值等于当前Node值:
    • (真)=>返回当前节点。
    • (False)=>(2。)
  2. 如果搜索值大于当前Node值:
    • (True)=>搜索正确的节点(如果正确的节点不为NULL,否则返回NULL)。
    • (假)=>(3。)
  3. 如果搜索值小于当前Node值:
    • (True)=>在左侧节点中搜索(如果右侧节点不为NULL,否则返回NULL)。

解决方案编码

public class Node {
    Node left,right;
    int value;

    // Solution 1
    public Node find(int v){
        if (v == this.value) return this;
        if (v > this.value && this.right != null) return this.right.find(v);
        if (v < this.value && this.left != null) return this.left.find(v);
        return null;
    }
    // Solution 2
    public Node find2(int v){
        Node node = this;
        while (node!=null){
            if (v == node.value)
                return node;
            if (v > node.value)
                node= node.right;
            else
                node= node.left;
        }
        return null;
    }
}

答案 3 :(得分:0)

您的代码不完整(有错别字)。您没有显示如何声明LargestNode或smallNode。

但是,由于您引用的行将继续在同一节点上递归调用,因此发生了堆栈溢出。添加一些调试信息以证明这一点(查找的第一行,进行类似System.out.println("called by "+Integer.toString(this.hashCode());的操作。例如,我怀疑这是另一种错字,可能是if(this.left!=null) result = this.left.find(v)