::::::::::::::
SimpleIntList.java
::::::::::::::
// The IntList interface defines a set of operations for an ordered collection
// (sequence) of integers. (GY edited from SR)
public interface SimpleIntList {
public int size();
public int get(int index);
public boolean isEmpty();
public void add(int value);
public void add(int index, int value);
public void remove(int index);
public void set(int index, int value);
public void clear();
}
::::::::::::::
SimpleAbstractIntList.java
::::::::::::::
// AbstractIntList provides a skeletal implementation of the IntList class.
// Subclasses need to define size(), get(int index), add(int value),
// add(index, value), remove(index), set(index, value), and clear().
// (GY edited from SR)
public abstract class SimpleAbstractIntList implements SimpleIntList {
// post: returns true if list is empty, false otherwise
public boolean isEmpty() {
return size()==0;
}
// post: throws an exception if the given index is out of range
protected void checkIndex(int index) {
if (index < 0 || index >= size())
throw new IndexOutOfBoundsException("illegal index");
}
}
::::::::::::::
SimpleArrayIntList.java
::::::::::::::
// ArrayIntList provides an implementation of the IntList interface backed by
// an array. This will provide O(1) performance for methods like get and set
// that access a particular element of the array. The underlying array will be
// doubled in size if necessary to accommodate add operations. The appending
// add has O(1) performance (amortized for doubling when full).
// (GY edited from SR)
public class SimpleArrayIntList extends SimpleAbstractIntList {
private int[] elementData; // list of integers
private int size; // current number of elements in the list
public static final int DEFAULT_CAPACITY = 100;
// post: constructs an empty list of default capacity
public SimpleArrayIntList() {
this(DEFAULT_CAPACITY);
}
// pre : capacity >= 0
// post: constructs an empty list with the given capacity
public SimpleArrayIntList(int capacity) {
if (capacity < 0)
throw new IllegalArgumentException("negative capacity");
elementData = new int[capacity];
size = 0;
}
// post: returns the current number of elements in the list
public int size() {
return size;
}
// pre : 0 <= index < size()
// post: returns the integer at the given index in the list
public int get(int index) {
checkIndex(index);
return elementData[index];
}
// post: appends the given value to the end of the list
public void add(int value) {
ensureCapacity(size + 1);
elementData[size] = value;
size++;
}
// pre: 0 <= index <= size()
// post: inserts the given value at the given index, shifting subsequent
// values right
public void add(int index, int value) {
if (index < 0 || index > size)
throw new IndexOutOfBoundsException("illegal index");
ensureCapacity(size + 1);
for (int i = size; i > index; i--)
elementData[i] = elementData[i - 1];
elementData[index] = value;
size++;
}
// pre : 0 <= index < size()
// post: removes value at the given index, shifting subsequent values left
public void remove(int index) {
checkIndex(index);
for (int i = index; i < size - 1; i++)
elementData[i] = elementData[i + 1];
size--;
}
// pre : 0 <= index < size()
// post: replaces the integer at the given index with the given value
public void set(int index, int value) {
checkIndex(index);
elementData[index] = value;
}
// post: list is empty
public void clear() {
size = 0;
}
// post: ensures that the underlying array has the given capacity; if not,
// the size is doubled (or more if given capacity is even larger)
public void ensureCapacity(int capacity) {
if (capacity > elementData.length) {
int newCapacity = elementData.length * 2 + 1;
if (capacity > newCapacity)
newCapacity = capacity;
int[] newList = new int[newCapacity];
for (int i = 0; i < size; i++)
newList[i] = elementData[i];
elementData = newList;
}
}
}
::::::::::::::
SimpleLinkedIntList.java
::::::::::::::
// LinkedIntList provides an implementation of the IntList interface backed by
// a singly-linked list. This will provide O(1) performance for adding at the
// front or back of the list. Methods like get and set will
// be O(n) for values in the middle of the list. (GY edited from SR)
public class SimpleLinkedIntList extends SimpleAbstractIntList {
private static class ListNode {
public int data; // data stored in this node
public ListNode next; // link to next node in the list
// post: constructs a node with given data and null links
public ListNode(int data) {
this(data, null);
}
// post: constructs a node with given data and given links
public ListNode(int data, ListNode next) {
this.data = data;
this.next = next;
}
}
private ListNode front; // first value in the list
private ListNode back; // last value in the list
private int size; // current number of elements
// post: constructs an empty list
public SimpleLinkedIntList() {
clear();
}
// post: returns the current number of elements in the list
public int size() {
return size;
}
// pre : 0 <= index < size()
// post: returns the integer at the given index in the list
public int get(int index) {
checkIndex(index);
ListNode current = gotoIndex(index);
return current.data;
}
// post: appends the given value to the end of the list
public void add(int value) {
if (front == null) {
front = new ListNode(value);
back = front;
} else {
back.next = new ListNode(value);
back = back.next;
}
size++;
}
// pre: 0 <= index <= size()
// post: inserts val at index, shifting subsequent values right
public void add(int index, int value) {
if (index < 0 || index > size)
throw new IndexOutOfBoundsException("illegal index");
if (index == 0)
addFirst(value);
else if (index == size)
add(value);
else {
ListNode current = gotoIndex(index - 1);
ListNode newNode = new ListNode(value, current.next);
current.next = newNode;
size++;
}
}
// add value as new first element of the list
private void addFirst(int value) {
front = new ListNode(value, front);
if (back == null)
back = front;
size++;
}
// pre : 0 <= index < size()
// post: removes value at the given index, shifting subsequent values left
public void remove(int index) {
checkIndex(index);
if (index == 0)
removeFirst();
else {
ListNode current = gotoIndex(index - 1);
current.next = current.next.next;
size--;
if (index == size)
back = current;
}
}
private void removeFirst() {
front = front.next;
if (front == null)
back = null;
size--;
}
// pre : 0 <= index < size()
// post: replaces the integer at the given index with the given value
public void set(int index, int value) {
checkIndex(index);
ListNode current = gotoIndex(index);
current.data = value;
}
// post: list is empty
public void clear() {
front = null;
back = null;
size = 0;
}
// pre : 0 <= index < size()
// post: returns the node at a specific index in O(n) time.
private ListNode gotoIndex(int index) {
ListNode current;
current = front;
for (int i = 0; i < index; i++)
current = current.next;
return current;
}
}