【发布时间】:2019-05-15 18:05:40
【问题描述】:
有没有办法在 O(N) 中迭代 TreeSet/TreeMap,同时能够删除迭代器当前指向的条目之外的其他条目?
这是一个使用 TreeSet 的简单示例。该集合包含正整数,我检查是否可以创建 N/2 对,例如每对包含 [x, 2*x]。我从最低键遍历地图,检查我们是否找到双精度并在找到时将其删除。 需要说明的是,这个例子只是为了说明,我不需要为例子本身寻找解决方案,而是要知道我是否可以在迭代时移除。
public boolean checkTree(TreeSet<Integer> tree){
for (Integer i: tree) {
int twice = i*2;
if(!tree.contains(twice)) return false;
else tree.remove(twice);
}
return true;
}
当然,如果我这样做,我会得到一个ConcurrentModificationException,因为我删除了一个元素而不使用iterator.remove()。但我不能使用该方法,因为我想删除其他元素。
这是我能想到的一种解决方法:
public boolean checkTree(TreeSet<Integer> tree){
while (tree.size() > 0) {
int twice = tree.pollFirst()*2;
if(!tree.contains(twice)) return false;
else tree.remove(twice);
}
return true;
}
但它会执行得更慢,因为调用 N 次 pollFirst() 是 O(N log N) 而不是 treeIterator 的 O(N)。由于 contains() 和 remove() 调用,整体复杂性确实会保持不变。
有没有办法在使用中序遍历遍历树的同时删除? TreeMap 类中有一个 successor() 方法,但它不是公开的。 这个问题实际上可能适用于所有 NavigableSet/NavigableMap 。
【问题讨论】:
标签: java binary-search-tree treemap treeset red-black-tree