CSCI 151 - Prelab 4 Link 'em up!

Due 9am, Monday, 29 February 2016

In this prelab, you will familiarize yourself with some of the design and implementation issues in the upcoming lab 4. Please write or type up your solutions, and hand in a paper copy before class on Monday. Remember, late prelabs receive zero credit.

Part 1 - Doubly Linked Lists

In this section of the lab you will implement your own doubly-linked list and a corresponding iterator.

Suppose your MyLinkedList<T> class is implemented as a doubly linked list and contains Node as a nested class:

public class MyLinkedList<T> extends AbstractList<T> {
    class Node {
        T data;
        Node prev, next;

        // more code here
    }

    // Class variables for MyLinkedList
    private Node head;
    private Node tail;
    private int  size;

    /* Lots more code will go here */
}

where both head and tail point to sentinel nodes pointing at each other and the size is 0 when the list is empty.

Empty linked list

  1. Assuming you have a zero-argument constructor for Node, write the constructor for the entire MyLinkedList class such that you end up with the above diagram.
    public MyLinkedList() {
        // Your answer will go here
    }
    













  2. Suppose you were to write a getNth method with the following header:
    private Node getNth(int index) {
        // Your answer will go here
    }
    
    that returns a reference to the Node at position index in the linked list. Write the method body for this method. For the prelab, you may assume that index is within the range 0 to size-1 (but check this in the actual lab!).












Your MyLinkedList class will generate a ListIterator when the factory method listIterator() (from AbstractList) is invoked.

An Iterator provides an easy way for someone to go through every item in your collection. The Iterator<T> interface has three methods:

// returns true if there are more items to see
public boolean hasNext();

// returns the next item in the list (and advances forward)
public T next();

// removes the last item returned by next()
public T remove();

A ListIterator supports going both backwards and forwards, so it also contains a couple of other methods

// returns true if there are more items to see going backwards
public boolean hasPrevious();

// returns the previous item in the list (and advances backwards)
public T previous();

After one call to next(), the iterator is logically in the state shown below (click to enlarge).

Linked list iterator after one call to next()

If you call next() you would get B, but if you called previous() instead you would get A. You don't want to always have to re-start at the head each time a user calls next(), so your ListIterator will need to keep track of its position in the list based on a Node instead of an index (which you might choose to use when constructing an ArrayList iterator).

  1. Fill in the following methods listed in this anonymous class:
    (For the prelab you may ignore throwing exceptions for going too far.)

    public ListIterator<T> listIterator() {
        return new ListIterator<T>() {
            // What class members do you want here?
    
    
    
            public boolean hasNext() {
                // what line of code goes here?
    
    
            }
            public T next() {
                // what lines of code go here?
    
    
    
    
    
            }
    
    
    
            public boolean hasPrevious() {
                // what line of code goes here?
    
    
            }
            public T previous() {
                // what lines of code go here?
    
    
    
    
    
            }
            // ... and some more in the next question ...
        };
    }
    
  2. What if we also wanted to implement both a remove() method that removes the most recently returned item from either next() or previous()? (In the above diagram it would remove A since we had just called next()).

    We also want an add(x) method that adds a new item just before whatever would have been returned by next() but just after whatever would have been returned by previous()? (This would put x in between A and B in the above diagram.)

    Give brief method bodies for these as well:

            public void remove() {
                // what lines of code go here?
    
    
    
    
            }
    
            public void add(T x) {
                // what lines of code go here?
    
    
    
    
    
    
            }
    
Last Modified: September 24, 2015 - Benjamin A. Kuperman - original by Alexa Sharp VI Powered