2

这是我算法中的一段代码:

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中的某些东西?

4

2 回答 2

6

Java 总是对方法调用使用按值传递。当您将引用类型传递给方法时,会生成引用的副本

以下行更改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);
于 2012-08-12T00:51:54.870 回答
-1

在 Java 中,引用是 C++ 指针和引用的混合体。有时,它们的行为类似于 C++ 指针,而有时,它们的行为类似于 C++ 引用。在进行赋值、作为参数传递给函数或在相等性测试中使用时,它们的行为类似于指针,但在访问成员时,它们的行为类似于 C++ 引用。就是这样,在 Java 中编写 tx 总是被解释为相当于 t->x 用于 C/C++ 中的指针(或 tx 用于 C++ 引用,但与 Java 不同,C++ 引用永远不会像指针一样表现)。

此外,在 Java 和一般的面向对象编程中,大多数人不会认为用空变量表示一个空列表是一个好主意。一旦初始化,变量应该总是引用一个功能齐全的对象,因此,一个空列表应该由对象的内部状态来标识;不是通过使用空引用。使用函数的返回值重新分配一个节点,该节点本身作为参数传递给同一函数,这更像是一些老式的 C/C++ hacking,然后是正确的现代面向对象设计。因此,而不是:

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 已经有一套完整的集合(通用和非通用)来表示应该能够转换必须基本需求的树和列表。

于 2012-08-12T04:41:51.623 回答