【问题标题】:Java Array of Generic Nodes in a Binary Tree, can't create nil node二叉树中通用节点的Java数组,无法创建零节点
【发布时间】:2019-07-04 07:49:05
【问题描述】:

我遇到了与此问题类似的问题: Array of generic nodes Java

但是,将嵌套的 Node 类设为静态解决了一个问题,但为我创建了另一个问题。我写了一棵二叉树,每次节点的指针不应该指向任何东西(例如叶节点的左右指针或根的父指针)时,它实际上指向一个特殊的“nil”节点,其中不包含相关数据。 Nil 是二叉树的成员变量。

当我创建一个节点时,构造函数使所有指针都指向 nil。但是,如果我将 Node 类设为静态,以便创建节点数组(我需要为特定方法执行此操作),我会收到每个指针的错误消息“无法对非静态字段进行静态引用零。”但是,如果我将 nil 更改为静态,我会得到一个错误,上面写着“无法对非静态类型 T 进行静态引用”。 (我的节点保存参数化类型对象。)

这是我的 Node 类:

protected static class Node<T>{
    Node left, right, parent;
    T object;

    protected Node(T x) {
        object= x;
        left= nil;
        right= nil;
        parent= nil;
    }
}

这是 nil 指定和二叉树构造函数,它创建 nil 节点并使其成为根:

protected static Node<T> nil;

public BT() {
    nil= new Node<T>(null);
    root= nil;
}

如何让自己创建节点数组而不遇到这些静态与非静态问题?

【问题讨论】:

  • 当指针不应该指向任何东西时,你有什么理由不简单地使用null?此外,leftrightparent 字段可能应该是 Node&lt;T&gt; 类型,而不是原始类型 Node
  • 为什么 nil field 是静态的?是的,该类可能需要是静态的,但这并不意味着字段 nil 也是如此。
  • 我正在学习在线课程中的教科书(Pat Morin 的开放数据结构)。有时这家伙有一些非常复杂的代码,所以如果 nil 节点是不必要的,我不会感到惊讶。
  • @HovercraftFullOfEels 因为nil 是从静态上下文中引用的(在静态嵌套的Node 构造函数中)。
  • @HovercraftFullOfEels 我同意,但如果你想在不使用 null 值的情况下编写代码,那么就是这样。参见例如Are null references really a bad thing?我个人不同意。仅在类的实现中使用时,将 null 替换为 nil 并不能真正使代码不易出错。从 API 中消除 null,例如使用 Optional 是另一回事。

标签: java arrays static nodes non-static


【解决方案1】:

首先,永远不要使用 raw 泛型,因此请在 Node 字段中指定 &lt;T&gt;

protected static class Node<T> {
    Node<T> left, right, parent;
    T object;

接下来,要初始化nil,需要一个不同的构造函数:

protected Node() {
    left = this;
    right = this;
    parent = this;
}

现在您可以将nil 初始化为非静态对象,以保持类型安全:

protected Node<T> nil = new Node<>();

不过,与其为每棵树创建一个nil 对象,不如创建一个静态方法:

@SuppressWarnings("rawtypes")
private static Node NIL = new Node();

@SuppressWarnings({ "cast", "unchecked" })
protected static <T> Node<T> nil() {
    return (Node<T>) NIL;
}

【讨论】:

  • 是的,我注意到我对原始泛型的错误。我一直在添加和删除很多东西以尝试使事情正常进行,但是当我在这里发布时却错过了。
  • 这适用于创建nil节点,但是当使用其他构造函数创建其他节点时,由于上述原因,我仍然无法指向nil节点。您的建议是将它们指向自己,但是在创建新节点后,我必须更改所有方法中的实现以修复指针。这是我需要做的吗?如果我在构建新节点后指向 nil 节点,这甚至会起作用吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-28
  • 1970-01-01
  • 2020-07-19
  • 2022-11-30
  • 1970-01-01
相关资源
最近更新 更多