【问题标题】:Binary Search Tree insertion - root remains null二叉搜索树插入 - 根保持为空
【发布时间】:2015-08-28 10:48:07
【问题描述】:

我是 Java 新手,我想创建一个带有插入和前序遍历的二叉搜索树类,但是当我完成插入时,根对象仍然为 null,编译器在前序遍历期间抛出 NullPointerException。

我的节点类:

class Node {
    int info;
    Node left;
    Node right;

    public Node() {
        info = 0;
        left = null;
        right = null;
    }

    Node(int x) {
        info = x;
        left = null;
        right = null;
    }
}

我的二叉搜索树类:

public class BinarySearchTree {

    private Node root;

    public BinarySearchTree() {
        root = null;
    }

    private void insertPrivate(Node node, int x) {
        if(node == null) {
            node = new Node(x);
        } 
        else {
            if(x < node.info) {
                insertPrivate(node.left, x);
            } 
        else if (x > node.info) {
                insertPrivate(node.right, x);
            }
        }
    }

    public void insert(int x) {
        insertPrivate(root, x);
    }

    private void preorderPrivate(Node node) {
        if(node != null) {
            System.out.println(node.info);
            preorderPrivate(node.left);
            preorderPrivate(node.right);
        }
    }

    public void preorder() {
        preorderPrivate(root);
    }

    public static void main(String[] args) {
        BinarySearchTree t = new BinarySearchTree();
        t.insert(12);
        t.insert(13);
        t.preorder();
    }
}

【问题讨论】:

  • 我在进行前序遍历时也犯了一些错误。我没有检查节点是否为空。

标签: java binary-search-tree


【解决方案1】:

这个问题是对 Java 引用的误解,正如这部分代码所见。

  private void insertPrivate(Node node, int x) {
    if(node == null) {
        node = new Node(x);
    } 
    ....

Java 引用按值传递给函数参数。

让我举个例子来澄清一下。

Node root = new Node(x);
// root == Node(x);

doSomething(root);
// Pass Node(x) into function;

void doSomething(Node node) {
    // root == Node(x);
    // node == Node(x); 

    node = new Node(y); // This updates node but not root
    // root == Node(x);
    // node == Node(y);

}    

您将不得不重组您的程序。一种方法是让insertPrivate 返回Node 并将该值分配给root。它不是最有效的,但它会起作用。

public void insert(int x) {
    root = insertPrivate(root, x);
}

private Node insertPrivate(Node node, int x) {
    if(node == null) {
        node = new Node(x);
    } 
    else {
        if(x < node.info) {
            node.left = insertPrivate(node.left, x);
        } 
    else if (x > node.info) {
            node.right = insertPrivate(node.right, x);
        }
    }
    return node;
}

【讨论】:

  • 这是正确答案。它包括一些关于为什么 OP 版本失败的解释。干得好。
  • 没问题,数据结构示例可能是用 C++ 编写的,它能够通过引用(也称为双指针)传递引用(或指针),这将允许您实现原始策略。跨度>
【解决方案2】:

像这样更改insert(int x)

public void insert(int x) {
    if (root == nul)
        root = new Node(x);
    else
        insertPrivate(root, x);
}

【讨论】:

  • 现在它可以写入值 12,但之后会抛出异常。
  • 这也行不通,递归的情况下也行不通
【解决方案3】:

尝试: 左节点 = 新节点(); 右节点 = new Node();

【讨论】:

    【解决方案4】:

    您应该以某种方式返回新创建的节点并将其分配给父节点的左侧或右侧节点。试试这个:

    private Node insertPrivate(Node node, int x) {
        if(node == null) {
            node = new Node(x);
        } 
        else {
            if(x < node.info) {
                node.left = insertPrivate(node.left, x);
            } 
        else if (x > node.info) {
                node.right = insertPrivate(node.right, x);
            }
        }
        return node;
    }
    

    你的公共插入功能应该是:

    public void insert(int x) {
        root = insertPrivate(root, x);
    }
    

    preorderPrivate 也需要空值检查:

    private void preorderPrivate(Node node) {
        System.out.println(node.info);
        if (node.left != null)
            preorderPrivate(node.left);
        if (node.right != null)
            preorderPrivate(node.right);
    }
    

    【讨论】:

      猜你喜欢
      • 2021-12-27
      • 2014-02-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多