简体   繁体   English

Java二进制搜索树实现问题。

[英]Java Binary Search Tree implementation problem.!

I am developing a binary search tree in java. 我正在用Java开发二进制搜索树。 But i am facing certain difficulties in it. 但我在其中面临某些困难。 Here is the code 这是代码

class Node {

    Node left, right;
    Integer data;

    Node(Integer d, Node left, Node right) {
        this.data = d;
        this.left = left;
        this.right = right;
    }
}

class BinaryTree {

    Node root;

    public BinaryTree(Node root) {
        this.root = root;
    }

    void insert(int d)
    {
        if(root==null)
            root= new Node(d, null, null);
        insert(root,d);
    }
    void insert(Node root, int d) {
        if (root == null) {
            root=new Node(d,null,null);
        } else if (d > root.data) {
            insert(root.right, d);
        } else if (d < root.data) {
            insert(root.left, d);
        }
    }

    void inorder(Node root) {
        if (root != null) {
            inorder(root.left);
            System.out.println(root.data);
            inorder(root.right);
        }
    }
}

public class BST {

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String str = null;
        BinaryTree bt=new BinaryTree(null);
        while (!(str = br.readLine()).equalsIgnoreCase("0")) {
            bt.insert(Integer.parseInt(str));
        }
        bt.inorder(bt.root);
    }
}

The problem here i am facing is as in java there is only pass by value. 我在这里面临的问题是因为在Java中只有按值传递。 I am getting the root as null in every case except the first case in which i have passed the newly created root into it. 除了在第一种情况下,我将新创建的根传递给它之外,在每种情况下我都将根作为null。 Here when i am making a recursive call to the insert function by passing the value of either left or right of the root then in the new call the new root has been created if required for it but when the function gets over it's values are not reflected to the caller function's variable. 在这里,当我通过传递根的左边或右边的值来对插入函数进行递归调用时,则在新调用中,如果需要它,则会创建新的根,但是当函数移开时,不会反映出它的值调用方函数的变量。 In short the problem is due to the call by value being followed by the java. 简而言之,问题是由于java后面跟着按值调用。

Can anyone please suggest the solution for this problem? 谁能为这个问题提出解决方案?

Your calls to insert(root.right/left, d) do not change the original right/left nodes if they are null, but simply make the method arguments point to a new variable (which, as you noticed, in Java won't change the original reference). 您对insert(root.right/left, d)调用不会更改原始的右/左节点(如果它们为null),而只是使方法参数指向一个新变量(正如您所注意到的,在Java中不会更改原始参考)。 Your change to the first root works because you call a different method, insert(int) . 对第一个根的更改有效,因为您调用了另一个方法insert(int)

Have you considered making left and right BinaryTree s instead of Node s? 您是否考虑过制作左右BinaryTree而不是Node Also, instead of using "null", consider having an "empty" BinaryTree (with a null root and an isEmpty method). 另外,不要使用“空”,而应考虑使用“空” BinaryTree(具有空根和isEmpty方法)。

Note that conceptually , left and right are trees, not nodes, so the design will be cleaner. 请注意, 从概念上讲 ,左和右是树,而不是节点,因此设计会更简洁。


Example code. 示例代码。 Untested but the idea should be right: 未经测试,但想法应该是正确的:

class Node {

    BinaryTree left, right;
    Integer data;

    Node(Integer d, BinaryTree left, BinaryTree right) {
        this.data  = d;
        this.left  = left;
        this.right = right;
    }
} 

class BinaryTree {

    Node root;

    // Empty tree
    BinaryTree() {
        this(null);
    }

    BinaryTree(Node root) {
        this.root == root;
    }

    void insert(int d) {

        if (this.root == null) {

            // The tree was empty, so it creates a new root with empty subtrees
            this.root = new Node(d, new BinaryTree(), new BinaryTree());

        } else if (d > this.root.data) {
            this.root.right.insert(d);
        } else if (d < this.root.data) {
            this.root.left.insert(d);
        }
    }
}

Notes: 笔记:

  • I respected the style of your existing code. 我尊重您现有代码的风格。
  • This implementation will skip repeated elements. 此实现将跳过重复的元素。

Suggestions, 建议,

  • I wouldn't use an Integer if you mean to use an int value. 如果要使用int值,则不会使用Integer
  • If you are reproducing code which is in the JVM already, I would read how the code works there first (and copy what you need) 如果您正在复制已经在JVM中的代码,我将首先阅读代码在其中的工作方式(并复制所需的内容)
  • When I have a bug in my code, I use the debugger to work out what is going wrong. 当我的代码中有错误时,我将使用调试器找出问题所在。
  • I start with a the simplest unit I can make which shows the problem, and fixes that simple situation. 我从一个最简单的单元开始,它可以显示问题并解决该简单情况。

I would post the simplest unit test, which anyone can reproduce, and what you see in the debugger here if it doesn't make any sense. 我将发布任何人都可以复制的最简单的单元测试,以及如果没有任何意义的调试器,您将在此处看到。

This doesn't really answer your question, but is too long for a comment. 这并不能真正回答您的问题,但是评论太久了。 ;) ;)

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

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