因此,我想实现对树的严格定义-没有任何循环的图。递归是一个具有n个子树/子节点的节点。因此,每个节点都需要某种数据结构来将其与其n个子树相关联。
数组,列表,序列,有序集合:子级实际上没有排序。有一种特殊的树称为“有序树”,它确实将某种排序与节点的子级相关联,但这似乎不合适。
例如:
Tree(3,
Tree(4),
Tree(5)
) == Tree(3,
Tree(5),
Tree(4)
)
集合:集合没有顺序,但也不包含重复项。从功能上讲,如果Tree(3)== Tree(3)是有意义的,但是我们想要重复的信息,因为一个节点可以有多个Tree(3)作为子树。
例如:
Tree(3,
Tree(4)
) != Tree(3,
Tree(4),
Tree(4)
)
包:无序集合,允许添加项目,但不允许任何删除。这似乎与可以删除树中的子项的事实不一致。
是否还有其他更合适的无序数据结构?我确定这以前是一个问题,什么是常见的解决方案?
谢谢!
答案 0 :(得分:0)
如果孩子的顺序无关紧要,并且允许重复,我认为List
就足够了。
由于没有保证,子代将在列表内排序或以正确的顺序插入,并且由于允许重复而不能使用Set
,因此我们可以定义如何比较两棵树,以便Tree(3, ArrayList(Tree(4), Tree(5))
和Tree(3, ArrayList(Tree(5), Tree(4))
可以比较相等。
一种方法是-在比较子项是否相等时,我们可以根据子项的值对子项进行排序并进行递归比较。
class Tree {
private Integer value;
private List<Tree> children;
// getter for value
// getter for children
public Tree(Integer value) {
this.value = value;
children = new ArrayList<>();
}
@Override
public boolean equals(Object other) {
if (other == this) {
return true;
}
if (!(other instanceof Tree)) {
return false;
}
Tree otherTree = (Tree) other;
return equalUtil(this, otherTree);
}
private boolean equalUtil(Tree lhs, Tree rhs) {
if(lhs == null && rhs == null) {
return true;
}
if(lhs == null || rhs == null) {
return false;
}
if(lhs.children.size() != rhs.children.size()) {
return false;
}
// copying the children into another list to not altering
// the tree's data ordering
lhsChildren = lhs.children;
Collections.sort(lhsChildren, new TreeComparator());
rhsChildren = rhs.children;
Collections.sort(rhsChildren, new TreeComparator());
for(int i = 0; i < lhsChildren.size(); i++) {
if(!equalUtil(lhsChildren[i], rhsChildren[i])) {
return false;
}
}
return true;
}
static class TreeComparator implements Comparator<Tree> {
@Override
public int compare(Tree lhs, Tree rhs) {
return lhs.getValue().compareTo(rhs.getValue());
}
}
}