Java - 二叉树指针在初始化后仍然为空?
Java - Binary Tree pointer still null after initialization?
这个问题很抽象,很难描述和搜索,所以我来了。然而,这是一个非常简单的问题。
我有以下 class:
class Node<T>
{
Comparable data;
Node<T> left, right;
public Node(Comparable data)
{
this.data = data;
}
}
如果我有会怎样:
/*
* Imagine this root looks like the following:
* 10 (root)
* / \
null null
*/
Node root;
// Imagine we are inside of the insert method and this
// is the current value that is going to be inserted.
int valueIAmTryingToInsert = 5;
// As we see from the tree above, "child" WILL be null.
Node child = (valueIAmTryingToInsert.compareTo(root.data) < 0 ? root.left : root.right);
if (child == null)
{
child = new Node(data);
return true;
}
// Recursive statement would happen here.
注意 child 是指向 root
左边或右边 child 的指针。但是,如果我实例化 child
指向的节点会发生什么?在调用 child = new Node(data);
之后,树目前看起来像:
10 (root)
/ \
5 null
如果看起来不是那样,请解释原因。因为我的理解是即使 Node child
为 null,指针仍然是 指向 root
的 children 之一。我很确定这行不通,因为我的编辑在声明 child = new Node(data);
中用下划线 child
并声称 The value new Node(data) assigned to 'child' is never used
(即使它正在被使用)。
您永远不会将它分配给根节点作为其 "left"。
用简单的英语来说,这就是您的代码的作用:
-根的左边(或右边)是否为空?
-是的
-请创建一个新节点。
但是这个新节点和根节点之间没有关联。
您可能需要这样的东西:
Node root;
Node child;
Integer valueIAmTryingToInsert = 5;
if(valueIAmTryingToInsert.compareTo(root.data) < 0){
if(root.left == null){
root.left = new Node(valueIAmTryingToInsert);
}
child = root.left;
}else{
if(root.right == null){
root.right = new Node(valueIAmTryingToInsert);
}
child = root.right;
}
return true;
编辑:
此代码只是一个示例,但如果 root.data
为 null,则由于比较,您将得到 NullPointerException
。这是您可能会意识到并注意的事情。
编辑 2:
我看得出您仍然很困惑,主要问题是您必须记住 null
不是对对象的引用。它是一个 "mark" ,表示该对象尚未初始化。所以当我说 a = null; b = a
不像 a
和 b
指向同一个对象时(因为 null
不是有效的对象或引用),这意味着它们都有尚未初始化。它们是独立的自变量。然后当我初始化一个 a = new MyClass()
时,我要求 a
的内存引用,但 b 仍然指向内存中的任何地方。
将 null
视为告诉 "This object is pointing to nowhere" 的一种方式。
如果事情如你所想(如果我初始化 a
那么 b
也应该指向那里);那么程序中的每个空对象都应该指向 a
现在指向的位置。
你需要明白 child = new Node()
会改变你的指针指向的对象,而不是指针之前指向的对象的任何值,绝对不是其他指针指向的对象(比如 root.left
).
root.left
和 child
不是同一个变量,即使在调用 child = root.left
之后!它们只指向同一个对象。所以改变一个指向的东西不会影响另一个。
基本上,new Node()
在您的记忆中的某处创建了一个新对象。 child = new Node()
做同样的事情,除了之后它告诉变量 child 指向新创建的对象而不是之前指向的任何对象。
这个问题很抽象,很难描述和搜索,所以我来了。然而,这是一个非常简单的问题。
我有以下 class:
class Node<T>
{
Comparable data;
Node<T> left, right;
public Node(Comparable data)
{
this.data = data;
}
}
如果我有会怎样:
/*
* Imagine this root looks like the following:
* 10 (root)
* / \
null null
*/
Node root;
// Imagine we are inside of the insert method and this
// is the current value that is going to be inserted.
int valueIAmTryingToInsert = 5;
// As we see from the tree above, "child" WILL be null.
Node child = (valueIAmTryingToInsert.compareTo(root.data) < 0 ? root.left : root.right);
if (child == null)
{
child = new Node(data);
return true;
}
// Recursive statement would happen here.
注意 child 是指向 root
左边或右边 child 的指针。但是,如果我实例化 child
指向的节点会发生什么?在调用 child = new Node(data);
之后,树目前看起来像:
10 (root)
/ \
5 null
如果看起来不是那样,请解释原因。因为我的理解是即使 Node child
为 null,指针仍然是 指向 root
的 children 之一。我很确定这行不通,因为我的编辑在声明 child = new Node(data);
中用下划线 child
并声称 The value new Node(data) assigned to 'child' is never used
(即使它正在被使用)。
您永远不会将它分配给根节点作为其 "left"。
用简单的英语来说,这就是您的代码的作用:
-根的左边(或右边)是否为空? -是的 -请创建一个新节点。
但是这个新节点和根节点之间没有关联。 您可能需要这样的东西:
Node root;
Node child;
Integer valueIAmTryingToInsert = 5;
if(valueIAmTryingToInsert.compareTo(root.data) < 0){
if(root.left == null){
root.left = new Node(valueIAmTryingToInsert);
}
child = root.left;
}else{
if(root.right == null){
root.right = new Node(valueIAmTryingToInsert);
}
child = root.right;
}
return true;
编辑:
此代码只是一个示例,但如果 root.data
为 null,则由于比较,您将得到 NullPointerException
。这是您可能会意识到并注意的事情。
编辑 2:
我看得出您仍然很困惑,主要问题是您必须记住 null
不是对对象的引用。它是一个 "mark" ,表示该对象尚未初始化。所以当我说 a = null; b = a
不像 a
和 b
指向同一个对象时(因为 null
不是有效的对象或引用),这意味着它们都有尚未初始化。它们是独立的自变量。然后当我初始化一个 a = new MyClass()
时,我要求 a
的内存引用,但 b 仍然指向内存中的任何地方。
将 null
视为告诉 "This object is pointing to nowhere" 的一种方式。
如果事情如你所想(如果我初始化 a
那么 b
也应该指向那里);那么程序中的每个空对象都应该指向 a
现在指向的位置。
你需要明白 child = new Node()
会改变你的指针指向的对象,而不是指针之前指向的对象的任何值,绝对不是其他指针指向的对象(比如 root.left
).
root.left
和 child
不是同一个变量,即使在调用 child = root.left
之后!它们只指向同一个对象。所以改变一个指向的东西不会影响另一个。
基本上,new Node()
在您的记忆中的某处创建了一个新对象。 child = new Node()
做同样的事情,除了之后它告诉变量 child 指向新创建的对象而不是之前指向的任何对象。