DoublyLinkedList(princeton版)如何删除方法有效?

时间:2016-12-04 07:07:17

标签: java algorithm data-structures doubly-linked-list

我试图理解DoublyLinkedList.java如何作为普林斯顿版本。请点击炒作链接以获取详细信息。

但是很长一段时间后,我仍然有两个问题需要完全理解这个实现。

问题1:删除方法中的if-else块如何工作?分支何时发生?

    // remove the element that was last accessed by next() or previous()
    // condition: no calls to remove() or add() after last call to next() or previous()
    public void remove() { 
        if (lastAccessed == null) throw new IllegalStateException();
        Node x = lastAccessed.prev;
        Node y = lastAccessed.next;
        x.next = y;
        y.prev = x;
        n--;

        // Below if-else condition I don't understand on which situation
        // "current == lastAccessed" will happen ?
        if (current == lastAccessed)
            current = y;
        else
            index--;
        lastAccessed = null;
    }

问题2:对于功能齐全的DoublyLinkedList,我们还应该在特定位置包含添加或删除节点,例如add(int index)remove(int index),但在princeton版本中我找不到任何关于此部分的提示那么我怎么能实现这两种方法呢?有人可以发布一些细节吗? (注意:此版本使用ListIterator

1 个答案:

答案 0 :(得分:1)

正如pvg所说,实施完全取决于用户和要求。此外, DoublyLinkedLists 不是很好的实现。

回答1 :假设你在列表中添加5个项目:3,2,53,23,1。然后在不先调用next()previous()的情况下执行以下操作:

iterator.remove();

它会抛出IllegalStateException,因为lastAccessed为空。为什么它为空?它为空,因为lastAccessed仅在next()previous()中更新。您尚未通过调用next()previous() 访问任何节点。

答案2 :您可以通过传递索引和要添加的节点的引用来添加。

public void add(int index, Node item) {
    if (index > size) throw new IndexOutOfBoundsException();

    Node cursor = head.next;
    int i = 0;
    while (i < index) {
        i++;
        cursor = cursor.next;
    }

    item.next = cursor.next;
    item.next.prev = item;
    cursor.next = item;
    item.prev = cursor;
    size++;
}

对于remove()功能,您可以实现此功能:remove(int index)。只需使用int i=0遍历列表,直到i < index,然后删除该节点。这将花费O(n)时间。或者更简单的方法是将引用传递给要删除的节点。这将需要O(1)。

实施取决于您的要求。如果需要通过索引删除并且没有对节点的引用,则必须遍历列表。或者只是传递要删除的节点的引用:

public void remove(Node item) {
    Node prev = item.prev;
    Node next = item.next;

    prev.next = next;
    next.prev = prev;

    item.next = null;
    item.prev = null;
}