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; } }