下面的代码将调用迭代器,并将整数发送回调用它的方法。我只是想知道是否通过使用a Iterator
可以使我的时间复杂度保持不变?(即O(1))。因为如果我将get与a一起使用LinkedList
,它将给我线性时间(即O(n))。
protected int least(int i) {
if(i >= digits.size()) {
return 0;
}
// temp++;
// System.out.println("Time taken=" + temp);
// long start = System.nanoTime();
ListIterator<Integer> itr1 = digits.listIterator(digits.size() - i);
// System.out.println("Time elapsed:" + (System.nanoTime() - start));
return itr1.previous();
}
如果创建一个Iterator
直接从i
a 的第n个索引开始的,则LinkedList
需要知道这也需要O(n)
。在中找到元素LinkedList
总是很慢的。
LinkedList
不只是记住了head
(和tail
列表)元素。其他所有元素都需要遍历整个列表来找到。
这是一个双向链接列表的图示(Java LinkedList
也是双向链接):
因此,如果您Iterator
在i
-th元素处创建起始位置,则它将在head
(或tail
)处起始并跟随指针直至i
-th元素。就像调用:
list.get(i);
这显然要付出代价O(n)
。
如果您需要基于索引的快速访问(也称为random-access),则可以考虑使用ArrayList
。它的结构允许访问O(1)
(它可以通过来直接计算元素在内存中的位置start + i * sizeof(type)
)。
提供这种快速随机访问的数据结构通常将接口RandomAccess
(文档和实现类)实现为指示符。
如前所述LinkedList
,不应通过进行基于索引的访问来迭代a list.get(i)
。因此,您应该使用Iterator
(或ListIterator
如果需要在迭代时修改列表)。
这是使用的通常方法Iterator
:
Iterator<E> iter = list.iterator();
while (iter.hasNext()) {
E element = iter.next();
...
}
或者,您也可以使用增强的for循环,该循环内部执行相同的操作,但看起来更紧凑:
for (E element : list) {
...
}
由于Java LinkedList
是双向链接的列表,因此您也可以从尾部开始,然后反向迭代该列表。因此,只需使用LinkedList#descendingIterator
方法(文档)代替LinkedList#iterator
。
最后是一个示例,显示了如何ListIterator
在迭代时用于修改列表:
ListIterator<E> listIter = list.listIterator(0);
while (listIter.hasNext()) {
E element = listIter.next();
...
// Remove the element last polled
listIter.remove();
// Inserts an element right before the last polled element
listIter.add(new Element());
}
您也可以ListIterator
使用hasPrevious()
和previous()
方法来前后遍历列表。这是它的文档。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句