toString导致StackOverflow错误

时间:2017-04-04 16:03:55

标签: java data-structures tree stack-overflow

我在我的Node类中覆盖了我的toString()以获取BinaryTree。现在它导致StackOverflow,我无法弄清楚原因。

我的BinaryTree.Java文件不完整,但它适用于到目前为止完成的iv。

基本上,如果我在Node.java中包含重写的toString(),我的代码会中断。我迷失了为什么。我想某想toString()以某种方式递归地调用Nodes

完整代码:

Node.Java

public class Node {
    Node right;
    Node left;
    String element;
    Node parent;

    public Node(){  

    }

    public Node(String element){
        this.element = element;

    }

    public String getElement(){
        return element;
    }

    public Node getLeft(){
        return left;
    }

    public Node getRight(){
        return right;
    }

    public void setElement(String str){
        element = str;
    }

    public void setRight(Node right){
        this.right = right;
    }

    public void setLeft(Node left){
        this.left = left;
    }

    public void setParent(Node parent){
        this.parent = parent;
    }

    public Node getParent(){
        return parent;
    }

    @Override
    public String toString() {
        return "Node [right=" + right + ", left=" + left + ", element=" + element + ", parent=" + parent + "]";
    }

}

BinaryTree.Java

import java.util.ArrayList;

public class BinaryTree {
    Node root;
    ArrayList<Node> tree = new ArrayList<>();


    //create a tree with a root node, and two empty nodes
    //root has no data
    public BinaryTree(Node root){
        tree = new ArrayList<>();
        this.root = root;
        root = new Node();  //parent of root will be set to null
        tree.add(root); // root at position 1 in arrayList
    }


    public BinaryTree(){

    }


    //assuming one of the children are null and there is a root
    public void insertNode(Node insertNode, Node parent){
        //setthis nodes parent to parent index.



        tree.add(insertNode); // add the node to end of the arraylist.
        insertNode.setParent(parent);  //sets the nodes parent node
        //if parents left is null, 
        if (parent.getLeft()==null){
            parent.setLeft(insertNode);
        }

        //else, its right is null
        else{
            parent.setRight(insertNode);
        }

    }

    public void insertRoot(Node node){
        if (tree.isEmpty()){  //add the root
            root = node;
            tree.add(node);

        }
        else{tree.add(node);}// add it, get its location in tree and then get its parent.
        //int index = tree.indexOf(node);// found the index of the nod  
    }


    public boolean isEmpty(){
        return root==null;
    }

    @Override
    public String toString() {
        return "BinaryTree [root=" + root + ", tree=" + tree + ", isEmpty()=" + isEmpty() + "]";
    }
}

TreeTest.java

public class TreeTest {



    public static void main(String[] args){
        //create empty tree & test
        BinaryTree myTree = new BinaryTree();
        System.out.println(myTree.isEmpty());
        System.out.println(myTree.toString());

        //create root node & test
        Node myRoot = new Node();  //Node@7852e922
        myTree.insertRoot(myRoot);
        myRoot.setElement("foo");
        System.out.println(myTree.isEmpty());
        System.out.println(myTree.toString());
        System.out.println(myTree.isEmpty());
        System.out.println(myTree.toString());


        //create a child node and test
        Node secondNode = new Node();  //Node@4e25154f
        myTree.insertNode(secondNode, myRoot);
        System.out.println(myTree.toString());   //code breaks here
        System.out.println(myRoot.getLeft());

    }}

3 个答案:

答案 0 :(得分:3)

看看你的toString()方法,我认为你对递归调用是正确的。

想象一下,某个节点A有一个子B.然后为了让A打印它的输出,它需要打印子节点B.为了让B打印它的输出,它需要打印父节点A.为了打印其输出,它需要打印子节点B,依此类推。

您可以更改toString()以仅打印父元素,这将停止循环。

答案 1 :(得分:1)

return "Node [... parent=" + parent + "]";

parent打印什么?

return "Node [right=" + right + ", left=" + left + "..."]";

leftright会打印什么?

return "Node [... parent=" + parent + "]";

根据需要继续......

解决方案:不要打印parent

您的节点A会打印其内容并将自身转换为String尝试将parent转换为String。然后,其父级P继续将自身转换为String,将其左右孩子转换为String,其中一个孩子再次A。而你又回到了段落的开头。

答案 2 :(得分:1)

打印父元素,而不是再次调用toString()的整个对象。

 @Override
 public String toString() {
    return "Node [right=" + right + ", left=" + left + ", element=" +
              element + ", parent=" + parent.element + "]";
 }