我正在从C迁移到Java并且我在递归方面遇到了困难,特别是因为在Java中你无法通过引用传递参数。
我正在寻找的不是强制Java通过引用传递参数的解决方案/技巧,而是推荐用Java解决此类问题的方法。
让我们在二叉树中插入递归节点:
void nodeInsert(Node n, int a) {
if (n == null)
n = new Node(a);
...
}
在C中,在执行结束时,树中的节点n
将指向新创建的节点。但是,在Java中,n
仍然是null
(因为n是按值传递的)。
针对此类问题建议的Java方法是什么? 我已经尝试了一些方法:
欢迎任何建议。
答案 0 :(得分:3)
在Java中,而不是使用引用变量,我们使用 return 值并将其分配给必须更改的变量。
Node nodeInsert(Node n, int a) {
if (n == null){
n = new Node(a);
return n;
}
else
{
....
return nodeInsert(n,a); //this is how a recursion is done.
....
}
}
如果您在递归时需要更多http://www.toves.org/books/java/ch18-recurex/,则会教你正确。
答案 1 :(得分:2)
实现的常用方法是维护节点本身内的节点关系。在各种JDK数据结构的实现中可以找到相当多的示例。因此,Node是值的容器,并包含对其他节点的引用,具体取决于数据结构。
如果节点之间需要子 - >父关系,则Node类看起来像
class Node<T> {
T value;
Node parent;
}
如果是insert,则创建一个新节点,将父引用设置为原始节点,然后返回新节点(这是可选的,但并不罕见,因此调用具有新生儿)
Node<T> insert(Node<T> parent, T value) {
Node<T> child = new Node<>();
child.value = value;
child.parent = parent;
return child;
}
是的,这会增加每个节点4个字节的小开销(或8个字节,在没有压缩指针的64位JVM上)
答案 2 :(得分:1)
我提出以下解决方案:
在类Node
中实现一个添加子节点的方法。这利用了OO可能性将数据和功能封装在一起。
更改nodeInsert
以返回新节点并将其添加到调用方中的父节点(也在注释中提及)。 nodeInsert
的职责是创建节点。这是一个明确的责任,方法签名显示了该方法的结果。如果创建时间不超过new Node()
,则可能无法为其创建单独的方法。
答案 3 :(得分:0)
您可以传递一个持有者对象,该对象又会引用您的新Node
对象
void nodeInsert(AtomicReference<Node> r, int a) {
if (r.get() == null)
r.set(new Node(a));
...
}
或者你可以为一个元素传递一个带空格的数组。
答案 4 :(得分:0)
在发布这个问题几个月之后,我意识到另一个解决方案实际上已经在java设计模式中考虑过了,但这里没有提到:Null Object Pattern。 缺点是每个空占用内存(在某些情况下,像大红黑树一样,这可能会变得很重要)。