我知道我们可以按照以下相反的顺序迭代列表:
List<Object> lst;
ListIterator<Object> i = lst.listIterator(lst.size());
但如果lst
是LinkedList
,效率会有效吗?我的意思是当我们获得指向列表末尾的ListIterator
时,实现是否在从乞讨到list.size()
位置的列表上迭代(花费O(n)
时间,其中{{1}是列表的大小)?
如果确实如此,有没有办法避免它?
答案 0 :(得分:1)
该文档指出LinkedList
是List和Deque接口&#34; 的&#34; 双重链接列表实现。因此,列表中的每个元素都引用了下一个和前一个元素。因此,迭代器应该以与自然顺序相反的顺序快速运行。
答案 1 :(得分:1)
javadoc声明LinkedList是一个双向链表,所以我希望descendingIterator()
返回一个指向列表尾部的迭代器,为O(1)
。请注意,descendingIterator
来自Deque
界面。
现在很难说语句lst.listIterator(lst.size())
是否也是O(1)
,因为如果listIterator
方法优化了来自lst.size()
的下一个元素的事实,则没有记录是尾巴。
答案 2 :(得分:1)
它不会遍历列表以生成迭代器。
寻找这些解决方案的最佳位置是Source Code。
if (index < (size >> 1)) {
next = header.next;
for (nextIndex=0; nextIndex<index; nextIndex++)
next = next.next;
} else {
next = header;
for (nextIndex=size; nextIndex>index; nextIndex--)
next = next.previous;
}
如您所见,它将尝试使用来自第一个节点或最后一个节点的最短路径到达索引。
答案 3 :(得分:1)
LinkedList还实现了Deque接口。
所以如果你把它实现为
Deque list = new LinkedList();
或者如果您还需要列表方法
LinkedList list = new LinkedList();
您可以使用
list.descendingIterator();
答案 4 :(得分:1)
您的代码不起作用,索引lst.size()
超出范围,也许您的意思是lst.size()-1
。但它仍然不是反向迭代器,它是一个前向迭代器,而不是从0开始将从您指定的元素开始。在这种情况下,您将只读取最后一个元素,然后到达结尾。
LinkedList
实现提供Deque的接口Deque.descendingIterator。在这种情况下,实例化迭代器和移动到下一个(前一个)元素都是O(1)
个操作。在第一种情况下,它是因为Deque
实现保留了对队列开始和结束的引用,在第二种情况下因为LinkedList
是一个双向链接列表,其中每个element继续引用其后继者和他的前任。