将二进制树节点值添加到ArrayList后,它们会发生更改

时间:2016-08-27 18:35:31

标签: java loops arraylist tree

首先,我知道必须在每次迭代中创建一个新的Tree实例,因为不重用同一个对象,并且还有thisthis线程的静态对象。我想我已经检查了代码的每一部分。

所以,我正在测试下面的代码。关于它的作用的一些信息:

第一个循环遍历一个Root节点列表,子节点形成二叉树。我为每个根节点创建一个树对象并将其添加到该对象中,该对象还包含两个用于树中所有节点的arraylist,另一个用于叶子。在循环中,我还将数字随机设置到从1到n的每个树中的每个叶子(其中n是树中叶子的数量),并将树添加到arrayList:possibleTrees。

问题: 在第一个循环中,当我遍历每棵树的叶子并打印它们的数字时,它会相应地打印它们。但是在它完成并且我遍历可能的树上打印所有树的叶子后,许多值都会改变。

下面是4叶子树下的代码和输出。顶部打印两次,因为一个是整数的arraylist,第二个是直接从节点打印值

修改:链接到TreeNode

Edit2:添加了alltopologies类(http://)pastebin.com/sB9UV8T6

    ArrayList<Tree> possibleTrees = new ArrayList<Tree>();
    ArrayList<Integer> numbers = new ArrayList<Integer>();        
    for (int i = 0; i < numNodes; i++) {
        numbers.add(i + 1);
    }
    for (Node n : allTopologies.allBinaryTrees(numNodes)) {
        Tree tree = new Tree();

        tree.setNodesLists(n);

        Collections.shuffle(numbers);
        tree.setleafNums(n, numbers);
        tree.setRoot(n);

        possibleTrees.add(tree);

        System.out.println(numbers);
        System.out.print("[");
        for (Node l : tree.getLeaves()) {

            System.out.print(l.getLeafNum() + ", ");
        }
        System.out.println("]");
        System.out.println("");

    }
    System.out.println("-------------------------------");
    for (Tree t : possibleTrees) {
        System.out.print("[");
        for (Node l : t.getLeaves()) {

            System.out.print(l.getLeafNum() + ", ");
        }
        System.out.println("]");
        System.out.println("");
    }

输出:
 [3,2,1,4] [3,2,1,4,]

[2,4,1,3] [2,4,1,3,]

[2,4,1,3] [2,4,1,3,]

[1,3,2,4] [1,3,2,4]

[3,4,2,1] [3,4,2,1,]

[2,2,1,4]

[2,4,1,3]

[2,4,1,3]

[1,3,2,1,]

[3,4,2,1,]

提前致谢!

1 个答案:

答案 0 :(得分:1)

要使算法正常工作,您的树一定不能共享节点。

但是在allBinaryTrees()的内部循环中,您可以使用共享节点创建树:

    for (Node lt : possibleLeftSubtrees) {
        for (Node rt : possibleRightSubtrees) {
            // make a tree of a node with lt and rt as subtrees,
            // and add it to the result
            result.add(new Node(i,lt, rt));
        }
    }

如果possibleLeftSubtrees有一个节点且possibleRightSubtrees有两个节点,则创建两个共享左节点的结果树。

顺便说一下,您的Tree.clone()方法已损坏:

Node b = new Node(2);
Node a = new Node(1, b, null);
b.setParent(a);
System.out.println(a.clone());

将引发StackOverflowError,因为克隆a意味着克隆其左子b,这意味着克隆其父a,这意味着......无限添加。