首先,我知道必须在每次迭代中创建一个新的Tree实例,因为不重用同一个对象,并且还有this和this线程的静态对象。我想我已经检查了代码的每一部分。
所以,我正在测试下面的代码。关于它的作用的一些信息:
第一个循环遍历一个Root节点列表,子节点形成二叉树。我为每个根节点创建一个树对象并将其添加到该对象中,该对象还包含两个用于树中所有节点的arraylist,另一个用于叶子。在循环中,我还将数字随机设置到从1到n的每个树中的每个叶子(其中n是树中叶子的数量),并将树添加到arrayList:possibleTrees。
问题: 在第一个循环中,当我遍历每棵树的叶子并打印它们的数字时,它会相应地打印它们。但是在它完成并且我遍历可能的树上打印所有树的叶子后,许多值都会改变。
下面是4叶子树下的代码和输出。顶部打印两次,因为一个是整数的arraylist,第二个是直接从节点打印值
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,]
提前致谢!
答案 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
,这意味着......无限添加。