以下是我算法中的一段代码:
public void insert(int element) {
_insert(element, root);
System.out.println(root);
}
private void _insert (int element, Node t) {
if (t == null) {
t = new Node(null, element);;
return;
}
}
Node
这是预定义的类。
调用公共方法insert
时,将调用私有方法并检查树是否为空。如果是,则会在root
位置创建新节点。
输出应该是一个节点。但实际输出为null
,这意味着虽然root作为t传递给私有方法,但它不会更新。
这应该在带有指针的C ++下工作。也许我误解了Java中的一些东西?
答案 0 :(得分:6)
Java总是使用pass-by-value进行方法调用。将引用类型传递给方法时,会生成引用的副本。
以下行更改t
以引用新对象,但它不会更改原始变量root
:
t = new Node(null, element);
您可以更改方法以返回插入的节点,如下所示:
private Node _insert (int element, Node t) {
if (t == null) {
t = new Node(null, element);
}
return t;
}
并且这样打电话:
root = _insert(element, root);
答案 1 :(得分:-1)
在Java中,引用是C ++指针和引用的混合。有时,它们的行为类似于C ++指针,有时则像C ++引用一样。在进行赋值,作为参数传递给函数或在相等测试中使用时,它们的行为类似于指针,但在访问成员时,它们的行为类似于C ++引用。就是这样,在Java中编写tx总是被解释为类似于C / C ++中指针的t-> x(或者对于C ++引用而言是tx,但与Java不同,C ++引用从不像指针那样)。
此外,在Java和一般的面向对象编程中,大多数人不会考虑使用null变量来表示空列表,这是一个好主意。初始化后,变量应始终引用完整功能对象,因此,应通过对象的内部状态来标识空列表;不是通过使用空引用。使用函数的返回值来重新分配一个自身作为参数传递给同一函数的节点更像是一些老式的C / C ++黑客然后适当的现代面向对象设计。因此,而不是:
root = _insert(root, element);
你应该写一些类似的东西:
MyList root = new MyList();
root._insert (element);
和你班上的某个地方MyList:
private void _insert (int element) {
if (this.endNode == null) {
this.endNode = new Node();
} else {
this.endNode.nextNode = new Node();
this.endNote = this.endNote.nextNode;
}
this.endNode.element = element;
}
如果希望_insert函数能够在链表中的任意位置插入元素,那么您应该经过节点的父节点(或者将元素插入到第一个位置时为null)或者使用双链表。
顺便说一句,Java已经拥有一整套集合(通用和非通用)来表示应该能够隐藏必须满足基本需求的树和列表。