//---------------------------------------------------------------------------- // SortedABList.java by Dale/Joyce/Weems Chapter 6 // Sorted Array Based List // // Null elements are not permitted on a list. The list is unbounded. // // Index-based add and set operations are not supported. Invoking them will // result in the unchecked UnsupportedOperationException being thrown. // // Two constructors are provided: one that use the natural order of the // elements as defined by their compareTo method and one that uses an // ordering based on a comparator argument. In both cases clients should be // aware that equality of elements is determined by the comparison operation // and not by the equals method defined on the element class. //---------------------------------------------------------------------------- import java.util.*; // Iterator, Comparator public class SortedABList<T> implements ListInterface<T> { protected final int DEFCAP = 100; // default capacity protected T[] list; // array to hold list’s elements protected int numElements = 0; // number of elements in this list protected Comparator<T> comp; // set by find method protected boolean found; // true if element found, otherwise false protected int location; // indicates location of element if found, // indicates add index if not found public SortedABList() // Precondition: T implements Comparable { list = (T[]) new Object[DEFCAP]; comp = new Comparator<T>() { public int compare(T element1, T element2) { return ((Comparable)element1).compareTo(element2); } }; } public SortedABList(Comparator<T> comp) { list = (T[]) new Object[DEFCAP]; this.comp = comp; } protected void enlarge() // Increments the capacity of the list by an amount // equal to the original capacity. { // Create the larger array. T[] larger = (T[]) new Object[list.length + DEFCAP]; // Copy the contents from the smaller array into the larger array. for (int i = 0; i < numElements; i++) { larger[i] = list[i]; } // Reassign list reference. list = larger; } protected void find(T target) // Searches list for an occurrence of an element e such that // compare(e, target) == 0. If successful, sets instance variables // found to true and location to the array index of e. If // not successful, sets found to false and location to the // array index where target should be inserted. { location = 0; found = false; if (!isEmpty()) recFind(target, 0, numElements - 1); } protected void recFind(T target, int first, int last) // Used by find. { int result; if (first > last) { found = false; result = comp.compare(target, list[location]); if (result > 0) location++; // adjust location to indicate insert index } else { location = (first + last) / 2; result = comp.compare(target, list[location]); if (result == 0) // found target found = true; else if (result > 0) // target too high recFind(target, location + 1, last); else // target too low recFind(target, first, location - 1); } } public boolean add(T element) // Adds element to this list. { if (numElements == list.length) enlarge(); find(element); // sets location to index where element belongs for (int index = numElements; index > location; index--) list[index] = list[index - 1]; list[location] = element; numElements++; return true; } public boolean remove (T target) // Removes an element e from this list such that compare(e, target) == 0 // and returns true; if no such element exists, returns false. { find(target); if (found) { for (int i = location; i <= numElements - 2; i++) list[i] = list[i+1]; list[numElements - 1] = null; numElements--; } return found; } public int size() // Returns the number of elements on this list. { return numElements; } public boolean contains (T target) // Returns true if this list contains an element e such that // compare(e, target) == 0; otherwise, returns false. { find(target); return found; } public T get(T target) // Returns an element e from this list such that compare(e, target) == 0; // if no such element exists, returns null. { find(target); if (found) return list[location]; else return null; } public boolean isEmpty() // Returns true if this list is empty; otherwise, returns false. { return (numElements == 0); } public boolean isFull() // This list is unbounded so always eturns false. { return false; } public void add(int index, T element) // Throws UnsupportedOperationException. { throw new UnsupportedOperationException("Unsupported index-based add attempted on sorted list."); } public T set(int index, T newElement) // Throws UnsupportedOperationException. { throw new UnsupportedOperationException("Unsupported index-based set attempted on sorted list."); } public T get(int index) // Throws IndexOutOfBoundsException if passed an index argument // such that index < 0 or index >= size(). // Otherwise, returns the element on this list at position index. { if ((index < 0) || (index >= size())) throw new IndexOutOfBoundsException("illegal index of " + index + " passed to ABList get method.\n"); return list[index]; } public int indexOf(T target) // If this list contains an element e such that compare(e, target) == 0, // then returns the index of the first such element. // Otherwise, returns -1. { find(target); if (found) { // must adjust in case there are duplicate values while ((location != 0) && (comp.compare(list[location - 1], target) == 0)) location--; return location; } else return -1; } public T remove(int index) // Throws IndexOutOfBoundsException if passed an index argument // such that index < 0 or index >= size(). // Otherwise, removes element on this list at position index and // returns the removed element; all current elements at positions // higher than that index have 1 subtracted from their position. { if ((index < 0) || (index >= size())) throw new IndexOutOfBoundsException("illegal index of " + index + " passed to ABList remove method.\n"); T hold = list[index]; for (int i = index; i < numElements-1; i++) list[i] = list[i + 1]; list[numElements-1] = null; numElements--; return hold; } public Iterator<T> iterator() // Returns an Iterator over this list. { return new Iterator<T>() { private int previousPos = -1; public boolean hasNext() // Returns true if the iteration has more elements; otherwise returns false. { return (previousPos < (size() - 1)) ; } public T next() // Returns the next element in the iteration. // Throws NoSuchElementException - if the iteration has no more elements { if (!hasNext()) throw new IndexOutOfBoundsException("illegal invocation of next " + " in LBList iterator.\n"); previousPos++; return list[previousPos]; } public void remove() // Removes from the underlying representation the last element returned // by this iterator. This method should be called only once per call to // next(). The behavior of an iterator is unspecified if the underlying // representation is modified while the iteration is in progress in any // way other than by calling this method. { for (int i = previousPos; i <= numElements - 2; i++) list[i] = list[i+1]; list[numElements - 1] = null; numElements--; previousPos--; } }; } }
Email Me |
Office Hours |
My Home Page |
Department Home |
MCC Home Page