简体   繁体   English

BST简单插入并递归

[英]BST simple insertion with recursion

I am trying to write a small function to insert a node to a BST. 我正在尝试编写一个小的函数以将节点插入BST。 The "insert" function is working correctly. “插入”功能正常工作。 I changed it to "insert2", where it doesn't work. 我将其更改为“ insert2”,在这里它不起作用。 I cannot figure out why it doesn't work. 我不知道为什么它不起作用。 What is the difference between "insert" and "insert2" in runtime? 运行时中“ insert”和“ insert2”之间有什么区别?

Insert method 插入方式

public void insert(Node node, int x) {
    if (x < node.val) {
        if (node.left == null) node.left = new Node(x);
        else insert(node.left, x);
    } else {
        if (node.right == null) node.right = new Node(x);
        else insert(node.right, x);
    }
}

insert2 method insert2方法

public void insert2(Node node, int x) {
        if (node == null) {
            node = new Node(x);
            return;
        }
        if (x < node.val) insert2(node.left, x);
        else insert2(node.right, x);
    }

Definition of Node 节点定义

public class Node {
    int val;
    Node left, right;
    public Node (int _val) {
        this.val = _val;
    }
}

Thanks in advance. 提前致谢。

Java is a pass by value language . Java是一种价值传递语言 This means that when you pass a variable to a method, either primitive or objects, the method cannot change that variable since it doesn't know anything about that variable. 这意味着,当您将变量传递给基本或对象的方法时,该方法无法更改该变量,因为它对该变量一无所知。 The method has it's own variable and assigning anything new to a argument variable only persist in that scope and does not mutate other bindings or objects. 该方法具有其自己的变量,并且向参数变量分配任何新内容仅在该范围内持久,不会更改其他绑定或对象。

When you do have: 当您拥有:

public static void update(String str) {
  str = "changed";
}

And do: 并做:

String s = "hello";
update(s);
System.out.println(s);

It will print "hello" since although the address of "hello" was passed to update , update only update the local variable to the address of a new string. 它将打印“ hello”,因为尽管已将“ hello”的地址传递给update ,但update仅将本地变量更新为新字符串的地址。 Assignment never changed the variable that was used to apply the method or the objects both variables points to. 分配从未更改用于应用方法或两个变量都指向的对象的变量。

String h = "hello";
String w = "world";
String x = h; // x points to the same string as h
x = w;        // x got it's value changed to point to w
System.out.println(h + " " + w);

The last statement prints "hello world", not "world world" as if assignment mutated the previous object. 最后一条语句显示“ hello world”,而不是“ world world”,就好像赋值使先前的对象发生了变化。

So what happened in your insert methods? 那么insert方法发生了什么?

insert2 overwrites a local variable that happens to be null to a new Node, but it has nothing to do with the original argument passed. insert2覆盖一个本地变量 ,该变量对于新Node而言恰好为null,但与传递的原始参数无关。 The newly created node is only accessible from that scope so when it returns the new node is ready to be garbage collected. 新创建的节点只能从该范围访问,因此当它返回时,新节点已准备好进行垃圾回收。 The tree passed to the original method was never mutated thus it never gets a new value. 传递给原始方法的树从未被更改,因此它从未获得新值。

If you look at insert it takes a not null Node and alters right or left property on either that node or one of it's descendants. 如果您看一下insert它需要一个不为null的Node并更改该节点或其后代之一的right或left属性。 Thus when you inspect the original argument the tree has changed since it didn't mutate arguments, but the object itself. 因此,当您检查原始参数时,该树已更改,因为它没有更改参数,而是对象本身。

Mutating objects is not the same as mutating variables. 变异对象与变异变量不同。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM