我创建了一个程序,它将键/值对存储到二进制搜索树中。该类包含一个根指针,用于跟踪树的根节点。在构造函数中将This.root设置为null。
以下方法put(K,V)尝试将新的键/值对插入树中。如果密钥已存在于树中,则该方法返回与该密钥对应的现有值。如果不是,则通过辅助方法put(K,V,BNode)插入键/值对。 ***通常我会返回this.put(...),但在这段代码中我用return null替换它,以便我可以在它之前添加一个print语句来检查根节点是否实际被修改
我的程序无法插入第一个键/值对。我在我的插入中放置了print语句并放置方法来检查它们是否正常工作。在这种情况下,curr(只是this.root)在插入之前为null,正如预期的那样,因为我们从一个空树开始。我创建了一个新节点,并在insert()中调用return该节点。现在curr指向这个创建的节点。 print语句“curr key”+ curr.key打印出正确的密钥,表明此节点创建有效。但是当我尝试打印this.root.key时,我得到一个NullPointerException。第二种方法中的curr修改是否也在第一种方法中修改了this.root?
//this.root is the root node of this binary search tree
public V put(K key, V val) {
System.out.println("put reached");
this.put(key, val, this.root); // original return statement
System.out.println("root key: " + this.root.key); // checks if root node was modified
// THIS print statement returns a NullPointerException
return null; // dummy return statement
}
private V put(K key, V val, BNode curr) {
V originalValue = this.get(key, curr); // returns null if key does not exist
//else returns corresponding key value
if (originalValue == null) {
curr = this.insert(key, val, curr); // helper method which uses recursion to insert
System.out.println("curr key " + curr.key); // checks if curr was modified
this.size++;
this.state++;
}
return originalValue;
}
private BNode insert(K newKey, V newValue, BNode n) {
if (n == null) {
return new BNode(newKey, newValue);
} else if (newKey.compareTo(n.key) < 0) {
n.left = this.insert(newKey, newValue, n.left);
} else {
n.right = this.insert(newKey, newValue, n.right);
}
return n;
}
答案 0 :(得分:0)
第二种方法中的curr修改是否也在第一种方法中修改了this.root?
简答:不。这是因为root的值永远不会改变。
这应该有助于清理问题,并解释为什么这种情况比我能做得更好:Is Java "pass-by-reference" or "pass-by-value"?。
简而言之,如果您想要以root用户身份分配新节点,则需要明确地执行此操作,而不是尝试更改传递给方法的值,因为这只会更改curr所指向的值。
答案 1 :(得分:0)
感谢快速回复trappski
如果Java确实通过引用传递,那么我现在对我的程序所遇到的问题更有意义。但是,如果只修改一个重复的BNode,而不是原始的BNode,那么为什么这样的递归方法会起作用呢?
private BNode deleteMin(BNode n) {
if (n.left == null) {
return n.right;
}
n.left = this.deleteMin(n.left);
return n;
}