LinkedList - 使用Iterator“get()”更快地迭代

时间:2017-04-10 04:11:11

标签: java collections linked-list iterator

我正在读这本书:Data Structures and Algorithm Analysis in Java by Mark Weiss。有人可以解释在调用get(i)时如何使用迭代器减少运行时间?

书中的文字摘要:

enter image description here

enter image description here

2 个答案:

答案 0 :(得分:3)

这是因为get(i)将从链表的头节点开始并连续移动到下一个节点,直到它返回对i节点的引用,即O(n)因为在将引用返回给调用者之前,它必须经过n或更确切地说i个不同的节点。另一方面,迭代器将存储当前节点,并且每次对next()的连续调用将简单地使引用前进到指向当前节点之后的下一个节点,这是O(1)操作。

get(i)是通用的,并不假设您在列表中进行迭代,这意味着它不知道您之前查看的节点(如果有的话)。出于这个原因,它必须通过再次遍历列表的头部来重新访问i节点。使用迭代器假设迭代,这意味着您之前查看的节点,或者说另一种方式,您将在下一个查看的节点,被假定为 next 节点,因此迭代器可以优化通过存储对当前节点的引用。这样,它不必通过链表的头部来查找下一个节点。

答案 1 :(得分:3)

    Integer[] elements = new Integer[] { 4, 2, 7, 8, 1, 0, 3, 5, 9, 6 };

    List<Integer> arrayList = new ArrayList<>(Arrays.asList(elements));
    List<Integer> linkedList = new LinkedList<>(Arrays.asList(elements));

    for (int i = 0; i < elements.length; i++) { // Runs for O(n)
        Integer l1 = arrayList.get(i); // returns in O(1) 
        Integer l2 = linkedList.get(i); // returns in O(n)
    }
对于 ArrayList

get(index)直接从内存位置获取index处的元素。
因此,get(index)位于O(1)

对于 LinkedList

get(index)通过遍历LinkedList的head位置列表来获取index处的元素。没有指定的内存位置可以为LinkedList的给定索引元素预测。
因此,get(index)位于O(n)

ArrayList的总运行时间= O(1) * O(n) = O(n)
LinkedList的总运行时间= O(n) * O(n) = O(n^2)

使用 java.util.Iterator类

    Iterator iterator = arrayList.iterator();

    // total execution time: O(N)
    while (iterator.hasNext()) { // runs for each element iteratively
        System.out.print(iterator.next());
    }
    System.out.println();

    iterator = linkedList.iterator();

    // total execution time: O(N)
    while (iterator.hasNext()) { // runs for each element iteratively
        System.out.print(iterator.next());
    }
    System.out.println();

iterator.next()只是迭代到List中的下一个元素。这样做的好处是我们不需要从列表的头部搜索List NodeIterator class可帮助您将地址保留到node的当前List位置。

使用 for-each as iterator 可以实现相同的功能,它具有更简单的代码实现。

    for (Integer I : arrayList) { // runs for each element: total execution time: O(N)
        System.out.print(I); // gets in O(1)
    }

    System.out.println();

    for (Integer I : linkedList) { // runs for each element: total execution time: O(N)
        System.out.print(I); // gets in O(1)
    }

因此使用迭代器,
ArrayList的总运行时间= O(n)
LinkedList = O(n)

的总运行时间