如何删除原始树的节点?无论如何,不能通过传递对象引用并在另一个方法中将其设为 null 来删除它吗?
how to delete the nodes of the original tree? cannot delete it by passing the object reference and making it null in another method, anyway?
这里是一个BST的代码,以自下而上的方式遍历并尝试删除叶子节点,如果它的值等于"k",所以如果叶子被删除并且形成的新叶子的值为"k",我也正在删除它们。
所以这就是我以自下而上的方式遍历的原因。要删除叶子,我只是将节点引用分配给 null 但 实际上并没有删除它,因为 java 是按值传递的 , 无论如何我可以在代码的以下部分对原始树进行更改:
if(l==null&&r==null&&n.k==k){
n=null;
return n;
}
但是在打印树值之后,它显示出与以前相同的树,但是当我更改节点值时 n.k=0
值正在改变,但它没有采用空引用。
为什么没有将 null 分配给节点?
下面是代码,运行 此代码在 **************************
:
之后再次打印同一棵树
class Node{
Node(int k){
this.k = k;
}
int k;
Node right;
Node left;
}
public class Testing {
static void preOrder(Node n){
if(n==null);
else{
preOrder(n.left);
preOrder(n.right);
System.out.println(n.k);
}
}
static Node del_leaves(Node n,int k){
if(n==null)
return null;
else{
Node l=null,r=null;
if(n.left!=null)
l = del_leaves(n.left,k);
if(n.right!=null)
r = del_leaves(n.right,k);
if(l==null&&r==null&&n.k==k){
n=null;
return n;
}
else
return n;
}
}
public static void main(String args[]){
Node root = new Node(10);
Node a = new Node(5);
Node b = new Node(5);
Node c = new Node(5);
Node d = new Node(5);
Node e = new Node(5);
root.left=a;
root.right=b;
a.left=c;
a.right=d;
b.left=e;
preOrder(root);
Node ret_root = del_leaves(root,5);
System.out.println("*****************************");
preOrder(ret_root);
}
}
Java 总是按值调用。您会在 Node n
中获得参考文献的副本。所以 n=null
不会改变调用上下文中的引用。只有 local 引用变量 n
设置为 null。
由于您无法更改节点 n
,因此您明智地 return 它应该是的值 - null
或其旧值取决于它是否被删除.
问题是您没有使用那个 returned 值,因此您失去了那个优势。
使用 returned 值将新的左侧和右侧分配给您的树:
if(n.left!=null)
n.left = del_leaves(n.left,k);
if(n.right!=null)
n.right = del_leaves(n.right,k);
if(n.left ==null && n.right==null && n.k==k){
return null;
}
return n;
至于为什么直接给n
赋值不行,正如PeterMmm所说,Java是传值。要对此进行扩展讨论,包括一些很好的答案和图纸,请参考这个问题:Is Java "pass-by-reference" or "pass-by-value"?.
这里是一个BST的代码,以自下而上的方式遍历并尝试删除叶子节点,如果它的值等于"k",所以如果叶子被删除并且形成的新叶子的值为"k",我也正在删除它们。
所以这就是我以自下而上的方式遍历的原因。要删除叶子,我只是将节点引用分配给 null 但 实际上并没有删除它,因为 java 是按值传递的 , 无论如何我可以在代码的以下部分对原始树进行更改:
if(l==null&&r==null&&n.k==k){
n=null;
return n;
}
但是在打印树值之后,它显示出与以前相同的树,但是当我更改节点值时 n.k=0
值正在改变,但它没有采用空引用。
为什么没有将 null 分配给节点?
下面是代码,运行 此代码在 **************************
:
class Node{
Node(int k){
this.k = k;
}
int k;
Node right;
Node left;
}
public class Testing {
static void preOrder(Node n){
if(n==null);
else{
preOrder(n.left);
preOrder(n.right);
System.out.println(n.k);
}
}
static Node del_leaves(Node n,int k){
if(n==null)
return null;
else{
Node l=null,r=null;
if(n.left!=null)
l = del_leaves(n.left,k);
if(n.right!=null)
r = del_leaves(n.right,k);
if(l==null&&r==null&&n.k==k){
n=null;
return n;
}
else
return n;
}
}
public static void main(String args[]){
Node root = new Node(10);
Node a = new Node(5);
Node b = new Node(5);
Node c = new Node(5);
Node d = new Node(5);
Node e = new Node(5);
root.left=a;
root.right=b;
a.left=c;
a.right=d;
b.left=e;
preOrder(root);
Node ret_root = del_leaves(root,5);
System.out.println("*****************************");
preOrder(ret_root);
}
}
Java 总是按值调用。您会在 Node n
中获得参考文献的副本。所以 n=null
不会改变调用上下文中的引用。只有 local 引用变量 n
设置为 null。
由于您无法更改节点 n
,因此您明智地 return 它应该是的值 - null
或其旧值取决于它是否被删除.
问题是您没有使用那个 returned 值,因此您失去了那个优势。
使用 returned 值将新的左侧和右侧分配给您的树:
if(n.left!=null)
n.left = del_leaves(n.left,k);
if(n.right!=null)
n.right = del_leaves(n.right,k);
if(n.left ==null && n.right==null && n.k==k){
return null;
}
return n;
至于为什么直接给n
赋值不行,正如PeterMmm所说,Java是传值。要对此进行扩展讨论,包括一些很好的答案和图纸,请参考这个问题:Is Java "pass-by-reference" or "pass-by-value"?.