CSC 103 Lecture Notes Week 2
Lists, Stacks, and Queues
abstract class int {
    /**
     * Return the sum of the given integers x and y.
     */
    int "+"(int x, int y);
    /**
     * Return the difference of the given integers x and y.
     */
    int "-"(int x, int y);
    /**
     * Return the product of the given integers x and y.
     */
    int "*"(int x, int y);
    /**
     * Return the quotient of the given integers x and y.
     */
    int "/"(int x, int y);
    // Other int operations ...
}
abstract class array {
    /**
     * Construct an array from the given elements e1 through en.  This method
     * is invoked with the syntax "{e1, ..., en}".
     */
    array "{...}"(Object e1, ..., Object en);
    /**
     * Return the object at the ith position of the given array a.  This method
     * is invoked with the syntax "a[i]".
     */
    Object "[...]"(array a, int i);
    // Other array operations ...
}
abstract class LinkedList {
    /**
     * Constructs an empty list.
     */
    public LinkedList();
    /**
     * Returns the element at the specified position in this list.
     */
    public Object get(int index);
    /**
     * Replaces the element at the specified position in this list with the
     * specified element.
     */
    public Object set(int index, Object element);
    // ...
}
 
Figure 1: GeneralList storage and access operations.
/****
 *
 * Class ListAsArray illustrates the O(N) running time for the
 * <tt>putFirst</tt> method in an array-based implementation of a list.
 *
 */
public class ListAsArray {
    /**
     * Allocate a list of the default size of 100000.
     */
    public ListAsArray() {
        data = new Object[SIZE];
        length = 0;
    }
    /**
     * Add the given element to the front of this.
     */
    public void putFirst(Object element) {
        int i;                  // Traversal index
        /*
         * Move all of the elements to the right one position.
         */
        for (i = length; i > 0; i--) {
            data[i] = data[i-1];
        }
        /*
         * Put the given element in the front position.
         */
        data[0] = element;
        /*
         * Increment the current length by 1.
         */
        length++;
    }
    /** The array data representation */
    private Object[] data;
    /** Current length of list */
    private int length;
    /** The default list size */
    private static final int SIZE = 100000;
}
 
Figure 2: Linked list structure.
/****
 *
 * Class ListAsLinkedList illustrates the O(1) running time for the
 * <tt>putFirst</tt> method in an linked list implementation of a list.
 *
 */
public class ListAsLinkedList {
    /**
     * Allocate an empty list.
     */
    public ListAsLinkedList() {
        head = null;
        length = 0;
    }
    /**
     * Add the given element to the front of this.
     */
    public void putFirst(Object element) {
        /*
         * If the list is currently empty, make a ListNode for the given
         * element and make it the first in the list.
         */
        if (head == null) {
            head = new ListNode(element, null);
            length = 1;
        }
        /*
         * Otherwise, make a new node and splice it into the front.
         */
        else {
            head = new ListNode(element, head);
            length++;
        }
    }
    /** Pointer to head of list */
    private ListNode head;
    /** Current length of list */
    private int length;
    /****
     * Class ListNode is an element of linked list.  A ListNode has an Object
     * value field and a pointer to the next node in a list.
     */
    private class ListNode {
        /**
         * Construct a list node with the given value and next pointer.
         */
        public ListNode(Object value, ListNode next) {
            this.value = value;
            this.next = next;
        }
        /* The data value of this node */
        private Object value;
        /* Pointer to the next node in the list */
        private ListNode next;
    }
}
/**** * * Class BooksLinkedList is an alternate implementation of the LinkedList * example given in Section 3.2.3 of the text book. The differences between * this implementation and the book's are the following: * <ol>
 
Figure 3: Doubly-linked list.
 
Figure 4: Circular doubly-linked list.
/**
 * Sort this in ascending order, based on the ordering defined by the
 * compareTo method applied this' elements.  Return the sorted value of
 * this.
 */
public void sort() {
    int i, j;                       // Traversal indices
    ListNode nodeI, nodeJ;          // Traversal pointers
    /*
     * Outta here if this is empty.
     */
    if (length == 0) {
        return;
    }
    /*
     * Use a basic bubble sort algorithm.
     */
    for (i=0; i<length-1; i++) {
        for (j=length-1, nodeJ=tail.prev; i<j; j--, nodeJ=nodeJ.prev) {
            if (((Comparable)(nodeJ.value)).compareTo(nodeJ.next.value) > 0) {
                swapNodeValues(nodeJ, nodeJ.next);
            }
        }
    }
}
/**
 * Swap the values in the given two nodes.  The nodes themselves stay put.
 */
protected void swapNodeValues(ListNode n1, ListNode n2) {
    Object temp;            // Temp value;
    /*
     * Use standard swap logic.
     */
    temp = n1.value;
    n1.value = n2.value;
    n2.value = temp;
}
/****
 *
 * Class ListSearch illustrates the recursive and iterative algorithms for
 * binary search on arrays.
 *
 *
 * @author Gene Fisher
 * @version 11apr01
 *
 */
public class ListSearch {
    /**
     * Perform a recursive binary search of the given list for the given
     * element, between the given start and end positions.
     */
    protected int binarySearchRecursive(Object[] list, Object element,
            int startPos, int endPos) {
        /*
         * Base case is when the length of the startPos/endPos interval <= 1.
         * If length <= 0, return failure immediately.  If length = 1, return
         * successfully if the searched-for element is the element at the
         * interval point, otherwise return failure.
         */
        if ((startPos > endPos) || (list.length == 0)) {
            return -1;
        }
        if (startPos == endPos) {
            if (element.equals(list[startPos]))
                return startPos;
            else
                return -1;
        }
        /*
         * The recursive step is to compute the interval midpoint and then do
         * one of the following:
         *
         *     (a) If the searched-for element is at the midpoint, return
         *         successfully.
         *
         *     (b) If the searched-for element is less than the midpoint
         *         element, recursively search the lower half of the list.
         *
         *     (c) If the searched-for element is greater than the midpoint
         *         element, recursively search the upper half of the list.
         */
        int midpoint = (startPos + endPos) / 2;
        if (element.equals(list[midpoint]))
            return midpoint;
        else if (((Comparable)element).compareTo(list[midpoint]) < 0 )
            return binarySearchRecursive(list, element, startPos, midpoint - 1);
        else
            return binarySearchRecursive(list, element, midpoint + 1, endPos);
    }
    /**
     * Perform an interative binary search of the given list for the given
     * element, between the given start and end positions.  Assume the list is
     * not null.
     */
    protected int binarySearchIterative(Object[] list, Object element) {
        int startPos = 0;               // Initial start position
        int endPos = list.length - 1;   // Initial end position
        /*
         * Iterate through the list while the length of the startPos/endPos
         * interval is >= 1 and we haven't yet found the searched-for element.
         * For each loop iteration, compute the interval midpoint and then do
         * one of the following:
         *
         *     (a) If the searched-for element is at the midpoint, return
         *         successfully.
         *
         *     (b) If the searched-for element is less than the midpoint
         *         element, search the lower half of the list.
         *
         *     (c) If the searched-for element is greater than the midpoint
         *         element, search the upper half of the list.
         */
        while (startPos <= endPos) {
            int midpoint = (startPos + endPos) / 2;
            if (element.equals(list[midpoint]))
                return midpoint;
            else if (((Comparable)element).compareTo(list[midpoint]) < 0 )
                endPos = midpoint - 1;
            else
                startPos = midpoint + 1;
        }
        /*
         * Fail if we never find the element.
         */
        return -1;
    }
}