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