【问题标题】:Insert string in a Binary tree在二叉树中插入字符串
【发布时间】:2021-12-25 19:38:21
【问题描述】:

我正在尝试创建一个接受字符串的二叉树,但如果符号为 + 向左插入,则它使用“-”和“+”向左或向右移动,如果是 - 则向右插入。这是我正在尝试做的直观表示。

insert 方法现在应该只接受单词和一个符号,并基于该插入右侧或左侧

这是我的代码,但出现空指针错误。显然,我没有插入正确的顺序


public class BinaryTree {
    
    private static Node root = null;
    private static Node sign = null;

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        
        BinaryTree bt = new BinaryTree();
        bt.insert("to", "-");
        bt.insert("the", "+");
        bt.preorder();

    }
    
    private class Node {
        String data;
        String sign;
        Node left;
        Node right;
        
    
    public Node(String w) {
        data = w;
        left = right = null;
        
    }
    
//  public Node(String w, String s) {
//      data = w;
//      sign = s;
//      left = right = null;
//      
//  }
    
    
    } // -----------------end of Node
    
    private void insert(String val, String sign) {
        root = insert(root, val, sign);
        
    }
    
    Node insert(Node r, String data, String passSign) {
        if (r == null) {
            return new Node(data);
        }
        
        if(r.sign.equals(passSign)) {
            r.right = insert(r.right, data, passSign);
        } 
        else if (r.sign.equals(passSign)){
            r.left = insert(r.left, data, passSign);
        }
        return r;
    }
    
    public void preorder() {
        preorder(root);
    }
    
    public void preorder(Node p) {
        if (p != null) {
            System.out.println(p.data);
            preorder(p.left);
            preorder(p.right);
        }
    }

}

【问题讨论】:

  • r.sign.equals(passSign) 不符合你解释的逻辑。为什么sign 应该是树或节点的属性?另外,您为什么认为第二次评估此表达式会导致不同的结果?

标签: java insert binary-tree


【解决方案1】:

主要问题有:

  • BinaryTreeNode 实例都应该有一个 sign 成员。符号只在插入过程中起作用,一旦插入节点就没有意义了

  • r.sign.equals(passSign) 因此也不是要检查的正确条件。根据您的描述,您应该检查符号是否为“-”并向右走,否则向左走(“+”)。没有影响此决定的节点的状态passSign.charAt(0) == '-' 也是如此。

  • 在进行递归调用时,您不应再次传递相同的符号:它已被处理。取而代之的是,在消费的标志之后传递任何跟随的标志。为此,您可以使用substring

  • 图像显示了一个没有值的根节点。然而,您创建一个完全没有节点的树实例是正确的。所以你的insert 方法应该处理root 为空但sign 参数不是空字符串的情况。在这种情况下,应该创建一个root 节点,但它不应该保存目标数据,因为我们仍然应该在树中更深入。这个原则可以适用于任何节点,而不仅仅是根。所以预见到创建这样的“占位符”节点并给它们一些默认值(如“(null)”)。

没问题,但我发现以inorder 的顺序打印更有用,并缩进更深的节点。这样您就可以了解树的结构。

以下是更正后的代码:

public class BinaryTree {
    
    private static Node root = null;
    // No sign member needed;

    public static void main(String[] args) {
        BinaryTree bt = new BinaryTree();
        bt.insert("to", "-");
        bt.insert("the", "+");
        bt.insert("buy", "-+");
        bt.insert("imperial", "+-");
        bt.insert("afflication", "++");
        bt.inorder();
    }
    
    private class Node {
        String data;
        // No sign member needed;
        Node left;
        Node right;
            
        public Node(String w) {
            data = w;
            left = right = null;    
        }
    }
    
    private void insert(String val, String sign) {
        root = insert(root, val, sign);
    }
    
    Node insert(Node r, String data, String passSign) {
        // Check whether there is a sign
        if (passSign.length() == 0) {
            return new Node(data);
        }
        // If needed, create a placeholder node so to be able to descend further
        if (r == null) {
            r = new Node("(null)");
        }
        
        if (passSign.charAt(0) == '-') {
            // Extract the rest of the signs
            r.right = insert(r.right, data, passSign.substring(1, passSign.length()));
        } 
        else {
            r.left = insert(r.left, data, passSign.substring(1, passSign.length()));
        }
        return r;
    }
    
    public void inorder() {
        inorder(root, "");
    }
    
    // This method gives a bit more visual output
    public void inorder(Node p, String indent) {
        if (p != null) {
            inorder(p.left, indent + "  ");
            System.out.println(indent + p.data);
            inorder(p.right, indent + "  ");
        }
    }
}

【讨论】:

    猜你喜欢
    • 2022-01-03
    • 2013-04-02
    • 1970-01-01
    • 2023-03-15
    • 2015-04-11
    • 2016-01-17
    • 2015-02-13
    • 2019-08-26
    • 1970-01-01
    相关资源
    最近更新 更多