【发布时间】:2019-02-14 10:32:17
【问题描述】:
我一直在尝试通过将孩子分配给其父母然后通过it.remove() 删除它来有效地创建树:
for (OgOrganizationTreeDTO parent : parents) {
setChildren(parent, organizationTree);
}
这里是setChildren函数的实现
private void setChildren(OgOrganizationTreeDTO root, List<OgOrganizationTreeDTO> allOrganizations) {
if (allOrganizations.isEmpty()) {
return ;
}
Iterator<OgOrganizationTreeDTO> it = allOrganizations.iterator();
while (it.hasNext()) {
OgOrganizationTreeDTO potentialChild = it.next();
if (potentialChild.getIdParentId() != null && potentialChild.getIdParentId().equals(root.getId())) {
root.addChild(potentialChild);
it.remove();
setChildren(potentialChild, allOrganizations);
}
}
}
我正在使用 LinkedList,我得到一个 ConcurrentModificationException。我已经通过将allOrganizations 的副本传递给递归setChildren 函数解决了这个问题,就像new LinkedList<>(allOrganizations) 一样,但是复制部分需要O(n) 时间,我不希望这样。
我也尝试过使用LinkedBlockingQueue,但我发现删除需要O(n) 时间。
我想利用 LinkedList O(1) 删除,所以每次我添加一个孩子并在它上面重复时,列表会变小。
我还成功地使用HashSet 实现了一个解决方案,方法是将各个节点标记为可见,并将基本情况设置为hashSet.size() == allOrganizations.size(),但我仍然在相同大小的列表上重复出现,所以这对我没有帮助其他。
有什么方法可以实现我使用LinkedListO(1) remove 的目标,或者有没有更有效的替代方法?
【问题讨论】:
-
您可以尝试使用
ListIterator -
或者,如果您担心性能,您可以在不递归的情况下做到这一点 - 使用大哈希图来存储所有已处理的实体,您可以在列表上进行 2 次迭代
标签: java algorithm data-structures tree