CS-151 Labs > Lab 4. My LinkedList


Part 1. Doubly-Linked Lists

Your first task is to implement a doubly-linked list called MyLinkedList<T>. Add a new class called MyLinkedList in package lab4 to your project. Copy starter code from MyLinkedList.java.

The methods of MyLinkedList class are just a subset of methods in java.util.LinkedList, and your implementations should match the behavior of LinkedList.

Your class will extend AbstractList<T> and later in this lab you will create a ListIterator nested inside MyLinkedList.

In doubly-linked lists, the removal of items can be especially tricky as you need to be sure to properly update all of the pointers of the next and previous elements, as well as handle the special cases for removal from the front or tail. Keep a piece of paper with you and draw pictures to help with your coding. Nobody writes this code correctly without referring to pictures.

You should not allow null values to be inserted into the list; if the user of your class attempts to do so, you should throw a NullPointerException.

Constructor

You only need to have a single public constructor that creates an empty list and initializes all the necessary variables. The constructor is already implemented in the starter code.

Note that this implementation uses the ideas from the textbook chapter 5.17 about adding dummy nodes (also called sentinel nodes) for the head and the tail of the Linked List. These are special nodes with no data. They simplify the code as you would never need to test that your head or tail are null.

In this implementation, the initial empty list looks like this:

Empty list

Private Methods

First you need to implement two private helper methods, which you can then call during addition/removal of new elements.

private Node getNth(int index)
Returns the Node (not the node’s data) at a specified index.
private removeNode(Node n)
Removes a given node n from the linked list.

Public Methods

public boolean add(T data)
The boolean add() method adds an element to the end of the list, and is always successful. It is defined as boolean because it mimics the method definition in AbstractList.
public void add(int index, T data)
Add an element at position index.

Throw a NullPointerException if the user tries to add null.

Throw an IndexOutOfBoundsException as needed (same rules as for MyArrayList)

public T get(int index)
Return the element at position index.

Throw IndexOutOfBoundsException as needed.

public T set(int index, T data)
Set the value at index index to data, return the old value.

Throw a NullPointerException if data is null and throw an IndexOutOfBoundsException as needed.

public T remove(int index)
Remove (and return) the element at position index in this list.

Throw an IndexOutOfBoundsException as needed.

public void clear()
Remove all elements from the list.
public boolean isEmpty():
Returns true if the list is empty.
public int size()
Returns the number of elements in the list (not including sentinels).

Testing MyLinkedList

When you have finished your implementation, be sure to test it thoroughly before continuing.

You should be able to re-use the tests you wrote in Lab 3 for MyArrayList. Create a new JUnit test case called MyLinkedListTest.java and paste the code from MyArrayListTest.java into it. Then you can open up the file, rename the public class to be MyLinkedListTest, and then update the methods to use MyLinkedLists instead of MyArrayLists. Just change MyArrayList to MyLinkedList throughout so you get lines like this.

MyLinkedList<String> x = new MyLinkedList<String>();