Если порядок детей не имеет значения, и дублирование разрешено, я думаю, 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());
}
}
}