class Node
{
public Object data;
public Node next;
public Node previous;
}
public class LinkedList
{
private Node first; private Node last; ...
}
Singly-Linked:
public class LinkedList
{
. . .
public Object removeFirst()
{
if (first == null) { throw new NoSuchElementException(); }
Object element = first.data;
first = first.next;
return element;
}
. . .
}
What do we need to do to make this method work for doubly-linked lists?
previous reference of the initial node after
removallast reference of the LinkedList if
the last element was removedpublic class LinkedList
{
. . .
public Object removeFirst()
{
if (first == null) { throw new NoSuchElementException(); }
Object element = first.data;
first = first.next;
if (first == null) { last = null; } // List is now empty
else { first.previous = null; } return element;
}
. . .
}
Singly-linked:
public void addFirst(Object element)
{
Node newNode = new Node();
newNode.data = element;
newNode.next = first;
first = newNode;
}
What do we need to do to make this method work for doubly-linked lists?
previous reference of the second nodelast reference of the LinkedList if
the last element was insertedpublic void addFirst(Object element)
{
Node newNode = new Node();
newNode.data = element;
newNode.next = first;
if (first == null) { last = newNode; }
else { first.previous = newNode; }
first = newNode;
}
public void addLast(Object element)
{
Node newNode = new Node();
newNode.data = element;
newNode.previous = last;
if (last == null) { first = newNode; }
else { last.next = newNode; }
last = newNode;
}
addFirstfirst and lastprevious and nextremoveLast, getLastprevious methodLinkedList lst = new LinkedList();
lst.addLast("A");
lst.addLast("B");
lst.addLast("C");
ListIterator iter = lst.listIterator();
// The iterator is before the first element |ABC
iter.next();
// Returns “A”; the iterator is after the first element A|BC
iter.next();
// Returns “B”; the iterator is after the second element AB|C
iter.previous();
// Returns “B”; the iterator is after the first element A|BC
remove removes the last element that was returned by
next or previousremove—add adds
before the iteratorremove just remove the element before the
iterator? while (iter.hasNext()) if (iter.next() has some property) iter.remove();
while (iter.hasPrevious()) if (iter.previous() has some property) iter.remove();
public Object previous()
{
if (!hasPrevious()) { throw new NoSuchElementException(); }
isAfterNext = false;
isAfterPrevious = true;
Object result = position.data;
position = position.previous;
return result;
}
isAfterNext, isAfterPrevious flagsremoveprivate Node lastPosition()
{
if (isAfterNext) { return position; }
else if (isAfterPrevious)
{
if (position == null) { return first; }
else { return position.next; }
}
else { throw new IllegalStateException(); }
}
removeNode positionToRemove = lastPosition();
positionToRemove.previous.next = positionToRemove.next; positionToRemove.next.previous = positionToRemove.previous;
if (isAfterNext) { position = position.previous; }
previous
reference@Test void testAddLast()
{
LinkedList lst = new LinkedList();
check("", lst);
lst.addLast("A");
check("A", lst);
lst.addLast("B");
check("AB", lst);
}
public static void check(String expected, LinkedList actual)
{
int n = expected.length();
if (n > 0)
{
// Check first and last reference
assertEquals(expected.substring(0, 1), actual.getFirst());
assertEquals(expected.substring(n - 1), actual.getLast());
// Check next references
ListIterator iter = actual.listIterator();
for (int i = 0; i < n; i++)
{
assertEquals(true, iter.hasNext());
assertEquals(expected.substring(i, i + 1), iter.next());
}
assertEquals(false, iter.hasNext());
// Check previous references
for (int i = n - 1 ; i >= 0; i--)
{
assertEquals(true, iter.hasPrevious());
assertEquals(expected.substring(i, i + 1), iter.previous());
}
assertEquals(false, iter.hasPrevious());
}
else
{
// Check that first and last are null
try
{
actual.getFirst();
throw new IllegalStateException("first not null");
}
catch (NoSuchElementException ex)
{
}
try
{
actual.getLast();
throw new IllegalStateException("last not null");
}
catch (NoSuchElementException ex)
{
}
}
}