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