CS 46B - Lecture 16

Cover page image

Pre-class reading

Implementing Linked Lists

.

Adding at Head

public void addFirst(Object element)
{
   Node newNode = new Node(); 
   newNode.data = element;
   newNode.next = first; 
   first = newNode; 
}

Removing at Head

public class LinkedList
{
   . . .
   public Object removeFirst()
   {
      if (first == null) { throw new NoSuchElementException(); }
      Object element = first.data;
      first = first.next; 
      return element;
   }
   . . .
}

Iterator Class

Advancing Iterator

public Object next()
{
   if (!hasNext()) { throw new NoSuchElementException(); }
   previous = position; // Remember for remove
   isAfterNext = true;
   if (position == null)
   {
      position = first;
   }
   else
   {
      position = position.next;
   }
   return position.data;
}

.hasNext

public boolean hasNext()
{
   if (position == null)
   {
      return first != null;
   }
   else
   {
      return position.next != null;
   }
}

remove

public void remove()
{
   if (!isAfterNext) { throw new IllegalStateException(); }
   if (position == first)
   {
      removeFirst();
   }
   else
   {
      previous.next = position.next;  
   }
   position = previous;  
   isAfterNext = false;
}

Lecture 16 Clicker Question 1

Suppose we removed the lines

   if (!isAfterNext) { throw new IllegalStateException(); }

and

   isAfterNext = false;

from the remove method. What would happen if one called remove twice in a row?

  1. The preceding element would be always be removed
  2. The preceding element would only be removed if it was the first one
  3. The second call to remove would have no effect
  4. An exception would occur

add

public void add(Object element)
{
   if (position == null)
   {
      addFirst(element);
      position = first;
   }
   else
   {
      Node newNode = new Node();
      newNode.data = element;
      newNode.next = position.next;  
      position.next = newNode;  
      position = newNode;  
   }
   isAfterNext = false;  
}

Efficiency of Singly-Linked List Operations

Lecture 16 Clicker Question 2

Actually, the table from the last slide isn't true for the implementation that we just studied. Which of them is false?

  1. Add/remove at iterator position: O(1)
  2. Add/remove first element: O(1)
  3. Add last element: O(1)
  4. Remove last element: O(n)

Lecture 16 Clicker Question 3

Ok, so let's add a tail reference.

public class LinkedList
{
private Node first;
private Node last;
...
}

Now we need to update it in all methods that mutate the list. Here is ListIterator.remove:

public void remove()
{
   if (!isAfterNext) { throw new IllegalStateException(); }
   if (position == first)
   {
      removeFirst();
   }
   else
   {
      previous.next = position.next;  
   }
   if (___) ___; 
   position = previous;  
isAfterNext = false; }

What should be filled in for the two ___?

  1. position == last / position = previous;
  2. position == null / last = previous;
  3. position == last / last = previous;
  4. previous == last / last = position;