java - 这两种对BST插入操作的实现有什么区别?

标签 java data-structures binary-search-tree

有代码:

public class BST {
    public Node root;

    private class Node {
        int key;
        String value;
        int N;
        Node left, right;

        public Node(int k, String v, int n) {
            key = k;
            value = v;
            N = n;
        }
    }

    public String get(int key) {
        return get(root, key);
    }

    private String get(Node n, int k) {
        if(n == null) {
            return null;
        }
        if(k == n.key) {
            return n.value;
        } else {
            if(k < n.key) {
                return get(n.left, k);
            } else {
                return get(n.right, k);
            }
        }
    }

    //    This snippet puzzles me
    public void put(int key, String value) {
        root = put(root, key, value);
    }

    private Node put(Node n, int k, String v) {
        if(n == null) {
            return new Node(k, v, 1);
        }
        if(n.key == k) {
            n.value = v;
        } else {
            if(k < n.key) {
                n.left = put(n.left, k, v);
            } else {
                n.right = put(n.right, k, v);
            }
        }
        n.N = size(n.left) + size(n.right);
        return n;
    }
    //    snippet ends


    public static void main(String[] args) {
        BST r = new BST();
        r.put(2, "root");
        r.put(1, "left");
        r.put(3, "right");

        System.out.println(r.get(2));
        System.out.println(r.get(1));
        System.out.println(r.get(3));
    }


}

输出:

root
left
right

效果很好:)

但是,当我像这样更改 put 方法时:

    public void put(int key, String value) {
        put(root, key, value);
    }

    private void put(Node n, int k, String v) {
        if(n == null) {
            n = new Node(k, v, 1);
        }
        if(n.key == k) {
            n.value = v;
        } else {
            if(k < n.key) {
                put(n.left, k, v);
            } else {
                put(n.right, k, v);
            }
        }
        n.N = size(n.left) + size(n.right);
    }

我得到了输出

null
null
null

显然,新的 put 方法失败了。但为什么?在我看来,这两种不同的实现并没有太大区别。

最佳答案

当您更改分配时

n.left = put(n.left, k, v);

put(n.left, k, v);

(或与 n.right 相同),并且您在那里还没有节点,您正在为 n 变量分配一个新节点,但您没有更新从父级到子级的链接从递归调用返回时。因此,新节点将保持隔离,因为您要更改上次递归调用中 n 的引用,而不是 n.left(或 right)父级的引用。此外,我猜测当引用 n 的值将在最后一次递归调用结束时被释放时,由于没有其他引用指向新创建的节点,这最终将被垃圾收集器消除。

关于java - 这两种对BST插入操作的实现有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34020043/

相关文章:

java - paint() 不会在 JLabel 动画中被调用

javascript - 存储分步指南的数据结构

节点包含链表的 Java 二叉搜索树

java - 使用 logback 和 nohup 在 Debian 后台运行 java 应用程序

java - @Order 与 @Bean 注释的方法行为

r - 在 R 中合并时有没有办法更新现有变量?

java - 打印二叉搜索树中最大的 n 值

java - 为什么在我的 BST 中序遍历中显示的是指针而不是字符串?

java - 管理多个 Maven 项目的一致版本

c - 字符串集的数据结构