Java 为什么AbstractList.removeRange需要二次时间?
我可以在文档中看到:Java 为什么AbstractList.removeRange需要二次时间?,java,collections,big-o,time-complexity,Java,Collections,Big O,Time Complexity,我可以在文档中看到: java.util.AbstractList#removeRange 它需要二次时间: 此实现在fromIndex之前获得一个列表迭代器, 并反复调用ListIterator.next,后跟ListIterator.remove 直到整个范围被移除。注意:如果ListIterator.remove 需要线性时间,此实现需要二次时间 但是为什么呢??守则: protected void removeRange(int fromIndex, int toIndex) {
java.util.AbstractList#removeRange
它需要二次时间:
此实现在fromIndex之前获得一个列表迭代器,
并反复调用ListIterator.next,后跟ListIterator.remove
直到整个范围被移除。注意:如果ListIterator.remove
需要线性时间,此实现需要二次时间
但是为什么呢??守则:
protected void removeRange(int fromIndex, int toIndex) {
ListIterator<E> it = listIterator(fromIndex);
for (int i=0, n=toIndex-fromIndex; i<n; i++) {
it.next();
it.remove();
}
}
protectedvoidremoverange(int-fromfindex,int-toIndex){
ListIterator it=ListIterator(fromIndex);
for(int i=0,n=toIndex fromIndex;i重要的部分是“注意:如果ListIterator.remove需要线性时间,则此实现需要二次时间”。for循环需要线性时间,您是对的。但是,如果您在每次迭代中执行线性时间步,您会得到n*n=n^2
原因在于:
it.remove();
这可以是列表上的O(n)操作,在O(n)循环中调用
换句话说,如果是这样的话,你的真实循环会是这样的(我编的,但你明白了):
protectedvoidremoverange(int-fromfindex,int-toIndex){
ListIterator it=ListIterator(fromIndex);
对于(int i=0,n=toIndex-fromIndex;i
“这通常是列表上的O(n)操作”“通常”有点言过其实。对于ArrayList是O(n),但是对于LinkedList是O(1)。
protected void removeRange(int fromIndex, int toIndex) {
ListIterator<E> it = listIterator(fromIndex);
for (int i = 0, n = toIndex - fromIndex; i < n; i++) {
E item = it.next();
//it.remove();
for (int j = ; j < n; j++) {
if (list.get(j).equals(e)) {
list.remove(e);
break;
}
}
}
}