Say I have a java PriorityQueue (which java implements as a heap) that I iterate over to remove elements based on some criteria:
PriorityQueue q = new PriorityQueue(); ... Iterator it = q.iterator(); while(it.hasNext()){ if( someCriterion(it.next()) ) it.remove(); }
How long does each remove() operation take? I’m not sure whether it’s O(log(n)) or O(1).
If you’re using the Sun implementation, it’sFrom the Javadocs:O(log(n)).Other implementations could have different complexity.
Edit: The Javadocs don’t cover the performance of removing an element with an iterator, so I had to look up the source code. This is all relevant to the Sun implementation, and may differ in Apple’s version, GNU Classpath, etc. Sun’s source is available here; it is also included in the JDK, so you might already have it installed.
In the
PriorityQueue‘s iterator, the default case forremove()is to callPriorityQueue.removeAt(lastRet), wherelastRetis the index that was last returned bynext().removeAt()appears to beO(log(n))worst case (it might have to sift the queue, but doesn’t have to iterate).However, sometimes bad things happen. From the comments of
removeAt():When a non-null element is returned by
removeAt(), the iterator adds it to a special queue for later use: when the iterator runs out of elements in the queue, it then iterates through this special queue. Whenremove()is called during this second phase of iteration, the iterator callsPriorityQueue.removeEq(lastRetElt), wherelastRetEltis the last element returned from the special queue.removeEqis forced to use a linear search to find the correct element to remove, which makes itO(n). BUT it can check elements using==rather than.equals(), so its constant factor is lower thanPriorityQueue.remove(Object).So, in other words, removing with an iterator is technically
O(n), but in practice it should be quite a bit faster thanremove(Object).