Answers to Self-Study Questions

Test Yourself #1

Java code and conceptual pictures of resulting structures

Test Yourself #2

Question 1: l.getNext().setData("cat");

Question 2: l.setNext(new Listnode<String>("rat", l.getNext()));

Test Yourself #3

The list begins:

initial list structure

and after the code looks like:

final list structure

and this is correct.

Test Yourself #4

Here's the code for the add method that adds to the end of the list.

//**********************************************************************
// add
//
// Given: Object ob
//
// Do:    Add ob to the end of the list
//
// Implementation:
//        o create a new Listnode for ob, pointed to by the "next" field
//          of the last node in the list (which will be the header node if
//          the list is empty)
//        o change the lastNode pointer to point to the new node
//        o increment numItems.
//
//**********************************************************************
public void add(E ob) {
    lastNode.setNext(new Listnode<E>(ob));
    lastNode = lastNode.getNext();
    numItems++;
}

Test Yourself #5

Here's the code for the add method that adds at a given position.

//**********************************************************************
// add
//
// Given: int pos and Object ob
//
// Do:    Throw an exception if pos has a bad value.
//        Otherwise, add ob to the list at position pos (counting from zero)
//
// Implementation:
//        Check for a bad position and if so, throw an exception.
//        Otherwise:
//          If we're being asked to add to the end of the list,
//          call the "add to the end" method (that way we don't need
//          to worry about updating the lastNode pointer).  Otherwise:
//
//          o find the node n in position pos-1 (counting the header
//            node as being in position -1)
//
//          o create a new Listnode for ob, whose next field points to the
//            node after n and set n's "next" field to point to the new node
//
//**********************************************************************
public void add(int pos, E ob) {
    // check for bad position
    if (pos < 0 || pos > numItems) {
        throw new IndexOutOfBoundsException();
    }

    // if asked to add to end, let the other add method do the work
    if (pos == numItems) {
        add(ob);
        return;
    }

    // find the node n after which to add a new node and add the new node
    Listnode<E> n = items;
    for (int k = 0; k < pos; k++) {
        n = n.getNext();
    }
    n.setNext(new Listnode<E>(ob, n.getNext()));
    numItems++;
}

Test Yourself #6

Here's the code for the constructor.

//**********************************************************************
// LinkedList
//
// constructor for the LinkedList class
//
// Do:    Initialize the list to be empty (i.e., initialize the
//        linked list to have just a header node, pointed to by
//        both pointer fields, and initialize numitems to zero).
//
//**********************************************************************
public LinkedList() {
    lastNode = new Listnode<E>(null);
    items = lastNode;
    numItems = 0;
}

Test Yourself #7

operation linked list array
remove first O(1) O(N)
remove last O(N) O(1)

For linked list: To remove the first item from a list (with a header node) you only have to do l.setNext(l.getNext().getNext()), and this is O(1). To remove the last node you must traverse the list from the first node to get to the next-to-last node to do the delete, so this is O(N), where N is the size of the list.

For arrays: To remove the first item you must shift all the remaining items one position to the left to fill in the hole so this is O(N). To remove the last item there are no shifts because no items are to the right, so this is O(1).

Test Yourself #8

    // Returns "true" if the circular list pointed to by l contains a node
    // with data matching o.
    public boolean circularListContains(Listnode<E> l, E o) {
        if (l == null) {
            // empty list
            return false;
        }
        Listnode<E> current = l.getNext();
        for (;;) {
            if (current.getData().equals(o)) {
                return true;
            }
            if (current == l) {
                return false;
            }
            current = current.getNext();
        }
    }

Things to note about this code:

Test Yourself #9

    // Adds object "o" to the end of the list pointed to by "last"
    public void addLast(Listnode<E> last, E o) {
        Listnode<E> tmp = new Listnode<E>(o);
        if (last == null) {
            tmp.setNext(tmp);
        } else {
            tmp.setNext(last.getLast());
            last.setNext(tmp);
        }
        last = tmp;
    }

    // Adds object "o" to the start of the list pointed to by "last"
    public void addFirst(Listnode<E> last, E o) {
        addLast(last, o);
        last = last.getNext();
    }

    // Removes the first node from the list pointed to by "last"
    public void removeFirst(Listnode<E> last) {
        if (last == null) {
            throw new IndexOutOfBoundsException(
                            "attempt to remove from empty list");
        }
        if (last.getNext() == last) {
            // one-node list
            last = null;
        } else {
            last.setNext(last.getNext().getNext());
        }
    }