diff --git a/IntListReview.iml b/IntListReview.iml
index c90834f..ff79d70 100644
--- a/IntListReview.iml
+++ b/IntListReview.iml
@@ -7,5 +7,37 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/ArrayIntList.java b/src/ArrayIntList.java
new file mode 100644
index 0000000..5d195db
--- /dev/null
+++ b/src/ArrayIntList.java
@@ -0,0 +1,322 @@
+import java.lang.reflect.Array;
+import java.nio.Buffer;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+public class ArrayIntList implements IntList{
+ // Internal private representation
+ private int[] buffer;
+ private int size; // Num of positions used in the buffer
+ private final static int INITIAL_CAPACITY = 10;
+
+ public ArrayIntList() {
+ buffer = new int[INITIAL_CAPACITY];
+ size = 0;
+ }
+
+
+ /**
+ * Prepends (inserts) the specified value at the front of the list (at index 0).
+ * Shifts the value currently at the front of the list (if any) and any
+ * subsequent values to the right.
+ *
+ * Speed = Relatively SLow, Linear Time O(size), has to shift size items right
+ *
+ * @param value value to be inserted
+ */
+ @Override
+ public void addFront(int value) {
+ // check if full
+ if (size == buffer.length){
+ resize(2 * buffer.length);
+ }
+ // Open a spot at index 0 where value will be saved
+ // Shift everything over to the right by 1 position
+ for(int i = size; i > 0; i--){
+ buffer[i] = buffer[i-1];
+ }
+
+ // Put the value at position [0]
+ buffer[0] = value;
+ size++;
+ }
+
+
+ /**
+ * Appends (inserts) the specified value at the back of the list (at index size()-1).
+ *
+ * Speed = Fast, Constant Time if no Resize 0(1)
+ * Can be Slow if resize is involved
+ *
+ * @param value value to be inserted
+ */
+ @Override
+ public void addBack(int value) {
+ // Check to see if we still have the capacity in buffer
+ if (size == buffer.length) {
+ // If the size matches the capacity, then I know I'm "full" and I need to resize
+ // ( create a new larger buffer and copy the values over from the older smaller buffer)
+
+ // Make the newSize twice the existing capacity
+ resize(2 * buffer.length);
+ }
+
+ buffer[size] = value;
+ size++;
+ }
+
+ /**
+ * Inserts the specified value at the specified position in this list.
+ * Shifts the value currently at that position (if any) and any subsequent
+ * values to the right.
+ *
+ * Speed = Depends on index. Can be as slow as add front or as fast as add back.
+ * Worst case speed = add at index 0 (Linear) and resize is needed
+ * Best case speed = add at index (size) (Constant) and no resize needed
+ *
+ * @param index index at which the specified value is to be inserted
+ * @param value value to be inserted
+ * @throws IndexOutOfBoundsException if the index is out of range
+ */
+ @Override
+ public void add(int index, int value) {
+ if (index > size){
+ throw new IndexOutOfBoundsException("Index is longer than the length!");
+ }
+
+ // check if full
+ if (size == buffer.length){
+ resize(2 * buffer.length);
+ }
+
+ for (int i = size; i > index; i--){
+ buffer[i] = buffer[i-1];
+ }
+
+ buffer[index] = value;
+ size++;
+ }
+
+ /**
+ * Removes the value located at the front of the list
+ * (at index 0), if it is present.
+ * Shifts any subsequent values to the left.
+ *
+ * Speed = Slow, Linear Time O(size) / O(n)
+ */
+ @Override
+ public void removeFront() {
+ if (size == 0){
+ throw new IllegalStateException("Array is empty!");
+ }
+ for(int i = 0; i < size; i++){
+ buffer[i] = buffer[i+1];
+ }
+ size--;
+ }
+
+ /**
+ * Removes the value located at the back of the list
+ * (at index size()-1), if it is present.
+ *
+ * Speed = fast and Constant O(1)
+ */
+ @Override
+ public void removeBack() {
+ if (size == 0){
+ throw new IllegalStateException("Already empty!");
+ }
+ buffer[--size] = 0;
+ }
+
+ /**
+ * Removes the value at the specified position in this list.
+ * Shifts any subsequent values to the left. Returns the value
+ * that was removed from the list.
+ *
+ * Speed = Depends on index. Can be as slow as remove front or as fast as remove back.
+ * Worst case speed = remove at index 0 (Linear) with a shift of numbers left
+ * Best case speed = remove at index (size) (Constant)
+ *
+ * @param index the index of the value to be removed
+ * @return the value previously at the specified position
+ * @throws IndexOutOfBoundsException if the index is out of range
+ */
+ @Override
+ public int remove(int index) {
+ if (index > size){
+ throw new IndexOutOfBoundsException("Index must be in range");
+ }
+
+ int r = buffer[index];
+ for(int i = 0; i < size; i++){
+ if (i >= index){
+ buffer[i] = buffer[i+1];
+ }
+ }
+ size--;
+ return r;
+ }
+
+ /**
+ * Returns the value at the specified position in the list.
+ *
+ * Speed = Fast, Constant Time 0(1)
+ *
+ * @param index index of the value to return
+ * @return the value at the specified position in this list
+ * @throws IndexOutOfBoundsException if the index is out of range
+ */
+ @Override
+ public int get(int index) {
+ if (index < size){
+ return buffer[index];
+ }else{
+ throw new IndexOutOfBoundsException("Index is out of Range!");
+ }
+ }
+
+
+ /**
+ * Returns true if this list contains the specified value.
+ *
+ * Speed = depends on if value exists or not.
+ * Worst case = Linear time O(size) and value is not in list or the last index
+ * Best case = value = index 0
+ *
+ * @param value value whose presence in this list is to be searched for
+ * @return true if this list contains the specified value
+ */
+ @Override
+ public boolean contains(int value) {
+ for(int i = 0; i < size; i++){
+ if (buffer[i] == value){
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Returns the index of the first occurrence of the specified value
+ * in this list, or -1 if this list does not contain the value.
+ *
+ * Speed = depends on if value exists or not.
+ * Worst case = Linear time O(size) and value is not in list or the last index
+ * Best case = value = index 0
+ *
+ * @param value value to search for
+ * @return the index of the first occurrence of the specified value in this list
+ * or -1 if this list does not contain the value
+ */
+ @Override
+ public int indexOf(int value) {
+ for(int i = 0; i < size; i++){
+ if (buffer[i] == value){
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * Returns true if this list contains no values.
+ *
+ * @return true if this list contains no values
+ */
+ @Override
+ public boolean isEmpty() {
+ return size == 0;
+ }
+
+ /**
+ * Returns the number of values in this list.
+ *
+ * @return the number of values in this list
+ */
+ @Override
+ public int size() {
+ return size;
+ }
+
+ /**
+ * Removes all the values from this list.
+ * The list will be empty after this call returns.
+ */
+ @Override
+ public void clear() {
+ // Shrink the list back down to the original creation size
+ buffer = new int[INITIAL_CAPACITY];
+ size = 0;
+ }
+
+ /**
+ * Returns an iterator over elements of type {@code T}.
+ *
+ * @return an Iterator.
+ */
+ @Override
+ public Iterator iterator() {
+ return new ArrayIntListIterator();
+ }
+
+
+ // Speed = O(n) or O(size) - Linear Time because you have to visit every item
+ @Override
+ public String toString() {
+ if ( size == 0 ){
+ return "[]";
+ }
+ StringBuilder sb = new StringBuilder();
+ sb.append("[");
+
+ for (int i = 0; i < size; i++){
+ sb.append(buffer[i]);
+ sb.append(i == size-1 ? "" : ", "); // Only append the comma if it's not the last index
+ }
+
+ sb.append("]");
+ return sb.toString();
+ }
+
+ // Speed = "Slow", Linear Time O(n)
+ // Depends on size of array because it copies old array into new array
+ private void resize(int newSize) {
+ // create a new array that is of the new size
+ int[] temp = new int[newSize];
+
+ // copy over values from the existing buffer
+ for (int i = 0; i < size; i++) {
+ temp[i] = buffer[i];
+ }
+
+ // Make the switchover
+ buffer = temp;
+ }
+
+ // Nested or inner class (helper class)
+ public class ArrayIntListIterator implements Iterator{
+ private int currentPosition;
+
+ public ArrayIntListIterator(){
+ currentPosition = 0;
+ }
+
+ @Override
+ public boolean hasNext() {
+ return currentPosition < size();
+ }
+
+ @Override
+ public Integer next() {
+ // Just to be safe - make sure there is a next
+ if (!hasNext()) {
+ throw new NoSuchElementException();
+ }
+ int value = get(currentPosition);
+ currentPosition++;
+ return value;
+ }
+ }
+
+} // End of ArrayIntList
diff --git a/src/ArrayIntListTest.java b/src/ArrayIntListTest.java
new file mode 100644
index 0000000..bdcf2ac
--- /dev/null
+++ b/src/ArrayIntListTest.java
@@ -0,0 +1,535 @@
+import static org.junit.jupiter.api.Assertions.*;
+
+class ArrayIntListTest {
+
+ // addFront() Tests
+
+ @org.junit.jupiter.api.Test
+ void addFrontWithEmptyList() {
+ ArrayIntList theList = new ArrayIntList();
+ theList.addFront(42);
+ assertEquals(theList.get(0), 42);
+ }
+ @org.junit.jupiter.api.Test
+ void addFrontWithNonEmptyList() {
+ ArrayIntList theList = new ArrayIntList();
+ theList.addFront(42);
+ theList.addFront(22);
+ theList.addFront(8);
+ theList.addFront(99);
+ assertEquals(theList.get(0), 99);
+ }
+
+ @org.junit.jupiter.api.Test
+ void addFrontWithResize() {
+ ArrayIntList theList = new ArrayIntList();
+ for(int i=0; i < 10; i++){
+ theList.addFront(i);
+ }
+ theList.addFront(42);
+ assertEquals(theList.get(0), 42);
+ }
+
+ @org.junit.jupiter.api.Test
+ void addFrontWithMultipleResizes() {
+ ArrayIntList theList = new ArrayIntList();
+ for(int i=0; i < 100000; i++){
+ theList.addFront(i);
+ }
+ theList.addFront(42);
+ assertEquals(theList.get(0), 42);
+ }
+
+ // addBack() Tests
+ @org.junit.jupiter.api.Test
+ void addBackWithEmptyList() {
+ ArrayIntList theList = new ArrayIntList();
+ theList.addBack(42);
+ assertEquals(theList.get(0), 42);
+ }
+
+ @org.junit.jupiter.api.Test
+ void addBackWithNonEmptyList() {
+ ArrayIntList theList = new ArrayIntList();
+ theList.addBack(1);
+ theList.addBack(2);
+ theList.addBack(3);
+ theList.addBack(42);
+ assertEquals(theList.get(theList.size()-1), 42);
+ }
+
+ @org.junit.jupiter.api.Test
+ void addBackWithResize() {
+ ArrayIntList theList = new ArrayIntList();
+ for(int i=0; i < 10; i++){
+ theList.addBack(i);
+ }
+ theList.addBack(42);
+ assertEquals(theList.get(theList.size()-1), 42);
+ }
+
+ @org.junit.jupiter.api.Test
+ void addBackWithMultipleResizes() {
+ ArrayIntList theList = new ArrayIntList();
+ for(int i=0; i < 1000000; i++){
+ theList.addBack(i);
+ }
+ theList.addBack(42);
+ assertEquals(theList.get(theList.size()-1), 42);
+ }
+
+
+
+ // add() Tests
+
+
+
+ @org.junit.jupiter.api.Test
+ void addWithEmptyList() {
+ ArrayIntList theList = new ArrayIntList();
+
+ theList.add(0, 42);
+ assertEquals(theList.get(0), 42);
+ }
+ @org.junit.jupiter.api.Test
+ void addWithNonEmptyListToMiddle() {
+ ArrayIntList theList = new ArrayIntList();
+ theList.addFront(50);
+ theList.addFront(24);
+ theList.addFront(15);
+ theList.addFront(50);
+ theList.addFront(22);
+ theList.addFront(15);
+
+ theList.add(2, 15);
+ assertEquals(theList.get(2), 15);
+ }
+
+ @org.junit.jupiter.api.Test
+ void addWithNonEmptyListToBack() {
+ ArrayIntList theList = new ArrayIntList();
+ theList.addBack(50);
+ theList.addBack(24);
+ theList.addBack(15);
+ theList.addBack(50);
+ theList.addBack(22);
+ theList.addBack(15);
+
+ theList.add(theList.size()-1, 15);
+ assertEquals(theList.get(theList.size()-1), 15);
+ }
+ @org.junit.jupiter.api.Test
+ void addWithIndexOutOfRange() {
+ ArrayIntList theList = new ArrayIntList();
+
+ theList.addFront(42);
+ theList.addFront(55);
+ theList.addFront(80);
+
+ assertThrows(IndexOutOfBoundsException.class, ()->{theList.add(5, 2);});
+ }
+
+ @org.junit.jupiter.api.Test
+ void addWithResize() {
+ ArrayIntList theList = new ArrayIntList();
+ for(int i=0; i < 10; i++){
+ theList.add(i, i*2);
+ }
+ theList.add(theList.size(), 42);
+ assertEquals(theList.get(theList.size()-1), 42);
+ }
+
+
+
+ // removeFront() Tests
+
+
+ @org.junit.jupiter.api.Test
+ void removeFront() {
+ ArrayIntList theList = new ArrayIntList();
+
+ theList.addFront(42);
+ theList.addFront(55);
+ theList.addFront(72);
+ theList.addFront(80);
+ theList.addFront(24);
+ theList.removeFront();
+ assertEquals(theList.get(0), 80);
+ }
+
+ @org.junit.jupiter.api.Test
+ void removeFrontMultipleTimes() {
+ ArrayIntList theList = new ArrayIntList();
+
+ theList.addFront(42);
+ theList.addFront(55);
+ theList.addFront(72);
+ theList.addFront(80);
+ theList.addFront(24);
+ theList.removeFront();
+ theList.removeFront();
+ theList.removeFront();
+ theList.removeFront();
+ assertEquals(theList.get(0), 42);
+ }
+
+ @org.junit.jupiter.api.Test
+ void removeFrontEmptyList() {
+ ArrayIntList theList = new ArrayIntList();
+
+ assertThrows(IllegalStateException.class, theList::removeFront);
+ }
+
+ @org.junit.jupiter.api.Test
+ void removeFrontAfterResize() {
+ ArrayIntList theList = new ArrayIntList();
+
+ for(int i=0; i < 100; i++){
+ theList.addBack(i);
+ }
+ theList.removeFront();
+
+ assertEquals(theList.get(0), 1);
+ }
+
+
+
+ // removeBack() Tests
+
+
+ @org.junit.jupiter.api.Test
+ void removeBackFromEmptyList() {
+ ArrayIntList theList = new ArrayIntList();
+
+ assertThrows(IllegalStateException.class, theList::removeBack);
+ }
+
+ @org.junit.jupiter.api.Test
+ void removeBackFromSingleItemList() {
+ ArrayIntList theList = new ArrayIntList();
+
+ theList.addBack(50);
+ theList.removeBack();
+ assertEquals(theList.size(), 0);
+ }
+
+ @org.junit.jupiter.api.Test
+ void removeBackFromListOf10() {
+ ArrayIntList theList = new ArrayIntList();
+
+ // Fill list with 10 items [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
+ for(int i=0; i < 10; i++){
+ theList.addBack(i);
+ }
+
+ // Remove the item from the back
+ theList.removeBack();
+
+ String out = theList.toString();
+ assertEquals(out, "[0, 1, 2, 3, 4, 5, 6, 7, 8]");
+ }
+
+
+
+ // remove() Tests
+
+
+ @org.junit.jupiter.api.Test
+ void removeFromMiddle() {
+ ArrayIntList theList = new ArrayIntList();
+ // Add 100 numbers to the list
+ for(int i = 0; i < 100; i++){
+ theList.addBack(i);
+ }
+ assertEquals(theList.remove(5), 5);
+ }
+
+ @org.junit.jupiter.api.Test
+ void removeFromBeginning() {
+ ArrayIntList theList = new ArrayIntList();
+ // Add 100 numbers to the list
+ for(int i = 0; i < 100; i++){
+ theList.addBack(i);
+ }
+ assertEquals(theList.remove(0), 0);
+ }
+
+ @org.junit.jupiter.api.Test
+ void removeFromEnd() {
+ ArrayIntList theList = new ArrayIntList();
+ // Add 100 numbers to the list
+ for(int i = 0; i < 100; i++){
+ theList.addBack(i);
+ }
+ assertEquals(theList.remove(theList.size()-1), 99);
+ }
+
+
+
+ // get() Tests
+
+
+ @org.junit.jupiter.api.Test
+ void getFromEmptyList() {
+ ArrayIntList theList = new ArrayIntList();
+ assertThrows(IndexOutOfBoundsException.class, ()->{
+ theList.get(0);
+ });
+ }
+
+ @org.junit.jupiter.api.Test
+ void getFromSingleItemList() {
+ ArrayIntList theList = new ArrayIntList();
+ theList.addFront(50);
+ assertEquals(theList.get(0), 50);
+ }
+
+ @org.junit.jupiter.api.Test
+ void getFromMultiItemList() {
+ ArrayIntList theList = new ArrayIntList();
+ theList.addFront(50);
+ theList.addFront(22);
+ theList.addBack(78);
+ theList.addBack(45);
+ theList.addBack(14);
+ assertEquals(theList.get(2), 78);
+ }
+
+ @org.junit.jupiter.api.Test
+ void getFromBack() {
+ ArrayIntList theList = new ArrayIntList();
+ theList.addFront(50);
+ theList.addFront(22);
+ theList.addFront(15);
+ theList.addFront(66);
+ assertEquals(theList.get(theList.size()-1), 50);
+ }
+
+ // contains() Tests
+ @org.junit.jupiter.api.Test
+ void containsWithEmptyList() {
+ ArrayIntList theList = new ArrayIntList();
+ assertFalse(theList.contains(5));
+ }
+
+ @org.junit.jupiter.api.Test
+ void containsWithSingleItem() {
+ ArrayIntList theList = new ArrayIntList();
+ theList.addFront(5);
+ assertTrue(theList.contains(5));
+ }
+
+ @org.junit.jupiter.api.Test
+ void containsWithMultiItem() {
+ ArrayIntList theList = new ArrayIntList();
+ theList.addFront(5);
+ theList.addFront(10);
+ theList.addFront(15);
+ theList.addFront(20);
+ assertTrue(theList.contains(15));
+ }
+
+
+
+ // indexOf() Tests
+
+
+ @org.junit.jupiter.api.Test
+ void indexOfEmptyList() {
+ ArrayIntList theList = new ArrayIntList();
+ assertEquals(theList.indexOf(0), -1);
+ }
+
+ @org.junit.jupiter.api.Test
+ void indexOfSingleItem() {
+ ArrayIntList theList = new ArrayIntList();
+ theList.addFront(10);
+ assertEquals(theList.indexOf(10), 0);
+ }
+
+ @org.junit.jupiter.api.Test
+ void indexOfFullList() {
+ ArrayIntList theList = new ArrayIntList();
+ theList.addFront(10);
+ theList.addFront(22);
+ theList.addFront(36);
+ theList.addFront(78);
+ theList.addFront(49);
+ theList.addFront(99);
+ assertEquals(theList.indexOf(78), 2);
+ }
+
+ @org.junit.jupiter.api.Test
+ void indexOfItemAtEnd() {
+ ArrayIntList theList = new ArrayIntList();
+ theList.addFront(10);
+ theList.addFront(56);
+ theList.addFront(99);
+ theList.addFront(28);
+ theList.addFront(75);
+ theList.addFront(73);
+ theList.addFront(58);
+ assertEquals(theList.indexOf(10), theList.size()-1);
+ }
+
+
+ // isEmpty() Tests
+
+
+ @org.junit.jupiter.api.Test
+ void isEmptyWithNoItems() {
+ ArrayIntList theList = new ArrayIntList();
+
+ assertTrue(theList.isEmpty());
+ }
+
+ @org.junit.jupiter.api.Test
+ void isEmptyWithSingleItem() {
+ ArrayIntList theList = new ArrayIntList();
+ theList.addFront(10);
+
+ assertFalse(theList.isEmpty());
+ }
+
+ @org.junit.jupiter.api.Test
+ void isEmptyWithMultipleItems() {
+ ArrayIntList theList = new ArrayIntList();
+ theList.addFront(10);
+ theList.addFront(22);
+ theList.addFront(76);
+ theList.addFront(48);
+ theList.addFront(90);
+
+ assertFalse(theList.isEmpty());
+ }
+
+ @org.junit.jupiter.api.Test
+ void isEmptyAfterRemoval() {
+ ArrayIntList theList = new ArrayIntList();
+ theList.addFront(10);
+ theList.addFront(22);
+ theList.removeFront();
+ theList.removeFront();
+
+ assertTrue(theList.isEmpty());
+ }
+
+
+
+ // size() Tests
+
+
+ @org.junit.jupiter.api.Test
+ void sizeWhileEmpty() {
+ ArrayIntList theList = new ArrayIntList();
+
+ assertEquals(theList.size(), 0);
+ }
+
+ @org.junit.jupiter.api.Test
+ void sizeWithSingleItem() {
+ ArrayIntList theList = new ArrayIntList();
+
+ theList.addFront(55);
+
+ assertEquals(theList.size(), 1);
+ }
+
+ @org.junit.jupiter.api.Test
+ void sizeWithMultipleItems() {
+ ArrayIntList theList = new ArrayIntList();
+
+ for(int i=0; i< 100; i++){
+ theList.addBack(i);
+ }
+
+ assertEquals(theList.size(), 100);
+ }
+
+
+
+ // clear() Tests
+
+
+ @org.junit.jupiter.api.Test
+ void clearWithItemsInList() {
+ ArrayIntList theList = new ArrayIntList();
+
+ theList.addFront(5);
+ theList.addFront(50);
+ theList.addFront(24);
+
+ theList.clear();
+ assertEquals(theList.size(), 0);
+ }
+
+ @org.junit.jupiter.api.Test
+ void clearWithEmptyList() {
+ ArrayIntList theList = new ArrayIntList();
+
+ theList.clear();
+ assertEquals(theList.size(), 0);
+ }
+
+ @org.junit.jupiter.api.Test
+ void clearAfterAddThenRemoveList() {
+ ArrayIntList theList = new ArrayIntList();
+
+ theList.addFront(5);
+ theList.addFront(50);
+ theList.removeFront();
+ theList.removeFront();
+
+ theList.clear();
+ assertEquals(theList.size(), 0);
+ }
+
+
+
+ // Iterator() tests
+
+
+ @org.junit.jupiter.api.Test
+ void iterator() {
+ ArrayIntList theList = new ArrayIntList();
+ theList.addFront(5);
+ theList.addFront(10);
+ theList.addFront(15);
+ theList.addFront(20);
+
+ int i = 0;
+ for(int n : theList){
+ assertEquals(n, theList.get(i));
+ i++;
+ }
+ }
+
+
+
+ // toString() Tests
+
+
+ @org.junit.jupiter.api.Test
+ void testToStringWithSingleItem() {
+ ArrayIntList theList = new ArrayIntList();
+
+ theList.addFront(5);
+ assertEquals(theList.toString(), "[5]");
+ }
+
+ @org.junit.jupiter.api.Test
+ void testToStringWithMultipleItems() {
+ ArrayIntList theList = new ArrayIntList();
+
+ theList.addFront(5);
+ theList.addFront(50);
+ assertEquals(theList.toString(), "[50, 5]");
+ }
+
+ @org.junit.jupiter.api.Test
+ void testToStringWithEmptyList() {
+ ArrayIntList theList = new ArrayIntList();
+
+ assertEquals(theList.toString(), "[]");
+ }
+}
\ No newline at end of file
diff --git a/src/LinkedIntList.java b/src/LinkedIntList.java
new file mode 100644
index 0000000..34ed692
--- /dev/null
+++ b/src/LinkedIntList.java
@@ -0,0 +1,357 @@
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+public class LinkedIntList implements IntList{
+ // Helper inner/nested class
+ public class Node {
+ int data; // Hold the data value
+ Node next; // Holds the address of the next node
+
+ public Node(){
+ data = 0;
+ next = null;
+ }
+
+ // T = 2 is O(n) constant time
+ public Node(int data, Node next){
+ this.data = data;
+ this.next = next;
+ }
+ // End of class node
+ }
+
+ // Fields for LinkedIntList class
+ private Node head; // Address of the first node in list
+ private int size; // Number of nodes/items in list
+
+
+ // T = 2 is O(1) constant time
+ public LinkedIntList(){
+ head = null;
+ size = 0;
+ }
+
+
+ /**
+ * Prepends (inserts) the specified value at the front of the list (at index 0).
+ * Shifts the value currently at the front of the list (if any) and any
+ * subsequent values to the right.
+ *
+ * T = 7 is O(1) constant time
+ *
+ * @param value value to be inserted
+ */
+ @Override
+ public void addFront(int value) {
+ head = new Node(value, head);
+ size++;
+ }
+
+ /**
+ * Appends (inserts) the specified value at the back of the list (at index size()-1).
+ *
+ * If list is empty, (if statement) then T = 5 is O(1) constant time
+ * If list is not empty, (else statement) then T = (2 * size) + 6 OR T = 2n + 6 which is O(n) linear time
+ *
+ * @param value value to be inserted
+ */
+ @Override
+ public void addBack(int value) {
+ // If the list is empty
+ if (head == null){
+ head = new Node(value, null);
+
+ }else{
+ // If the list is not empty
+ Node current = head;
+
+ // Loop and stop on last node in list (But not all the way to null)
+ while (current.next != null){
+ // move current forward
+ current = current.next;
+ }
+ // When I am here, current is referencing the last node
+ current.next = new Node(value, null);
+ }
+ // Increase the size of the list
+ size++;
+ }
+
+ /**
+ * Inserts the specified value at the specified position in this list.
+ * Shifts the value currently at that position (if any) and any subsequent
+ * values to the right.
+ *
+ * @param index index at which the specified value is to be inserted
+ * @param value value to be inserted
+ * @throws IndexOutOfBoundsException if the index is out of range
+ */
+ @Override
+ public void add(int index, int value) {
+ if (index > size){
+ throw new IndexOutOfBoundsException("Index is longer than the length!");
+ }
+ if (index == 0){
+ head = new Node(value, null);
+ }else{
+ Node newNode = new Node(value, null);
+ Node current = head;
+
+ // Traverse to the node before the specified index
+ for (int i = 0; i < index - 1; i++) {
+ current = current.next;
+ }
+
+ // Insert the new node in between
+ newNode.next = current.next;
+ current.next = newNode;
+
+
+ }
+ size++;
+ }
+
+ /**
+ * Removes the value located at the front of the list
+ * (at index 0), if it is present.
+ * Shifts any subsequent values to the left.
+ */
+ @Override
+ public void removeFront() {
+ if (size == 0){
+ throw new IllegalStateException("List is empty!");
+ }
+ if (head != null) {
+ Node current = head;
+ if (current.next != null){
+ head = current.next;
+ }else{
+ head = null;
+ }
+ size--;
+ }
+ }
+
+ /**
+ * Removes the value located at the back of the list
+ * (at index size()-1), if it is present.
+ */
+ @Override
+ public void removeBack() {
+ if (size == 0){
+ throw new IllegalStateException("List is empty!");
+ }
+ if (head != null){
+ Node current = head;
+ // Check if there is a next
+ if (current.next != null){
+ while (current.next.next != null){
+ current = current.next;
+ }
+ current.next = null;
+ }else{
+ head = null;
+ }
+ size--;
+ }
+ }
+
+ /**
+ * Removes the value at the specified position in this list.
+ * Shifts any subsequent values to the left. Returns the value
+ * that was removed from the list.
+ *
+ * @param index the index of the value to be removed
+ * @return the value previously at the specified position
+ * @throws IndexOutOfBoundsException if the index is out of range
+ */
+ @Override
+ public int remove(int index) {
+ if (size == 0){
+ throw new IndexOutOfBoundsException("Index is out of range!");
+ }
+ Node current = head;
+ for (int i = 0; i <= index; i++){
+ if (i == index){
+ Node removed = current;
+ current = current.next;
+ size--;
+ return removed.data;
+ }
+ if (current.next != null){
+ current = current.next;
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * Returns the value at the specified position in the list.
+ *
+ * O(n) linear - to get an item at an index. I have to start at the head
+ * and walk up to the size poisitons over
+ *
+ * @param index index of the value to return
+ * @return the value at the specified position in this list
+ * @throws IndexOutOfBoundsException if the index is out of range
+ */
+ @Override
+ public int get(int index) {
+ if (size == 0 || index > size){
+ throw new IndexOutOfBoundsException("The index is out of bounds");
+ }
+ Node current = head;
+ for (int i = 0; i <= index; i++){
+ if (i == index){
+ return current.data;
+ }
+ if (current.next != null){
+ current = current.next;
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * Returns true if this list contains the specified value.
+ *
+ * @param value value whose presence in this list is to be searched for
+ * @return true if this list contains the specified value
+ */
+ @Override
+ public boolean contains(int value) {
+ Node current = head;
+ while(current != null){
+ if(current.data == value){
+ return true;
+ }
+ current = current.next;
+ }
+ return false;
+ }
+
+ /**
+ * Returns the index of the first occurrence of the specified value
+ * in this list, or -1 if this list does not contain the value.
+ *
+ * @param value value to search for
+ * @return the index of the first occurrence of the specified value in this list
+ * or -1 if this list does not contain the value
+ */
+ @Override
+ public int indexOf(int value) {
+ int i = 0;
+ Node current = head;
+ while(current != null){
+ if (current.data == value){
+ return i;
+ }
+ current = current.next;
+ i++;
+ }
+ return -1;
+ }
+
+ /**
+ * Returns true if this list contains no values.
+ *
+ * @return true if this list contains no values
+ */
+ @Override
+ public boolean isEmpty() {
+ return size == 0;
+ }
+
+ /**
+ * Returns the number of values in this list.
+ *
+ * @return the number of values in this list
+ */
+ @Override
+ public int size() {
+ return size;
+ }
+
+ /**
+ * Removes all the values from this list.
+ * The list will be empty after this call returns.
+ */
+ @Override
+ public void clear() {
+ head = null;
+ size = 0;
+ }
+
+ /**
+ * Returns an iterator over elements of type {@code T}.
+ *
+ * @return an Iterator.
+ */
+ @Override
+ public Iterator iterator() {
+ return new LinkedIntListIterator();
+ }
+
+ // helper method (not required, but nice example
+ public void print() {
+ // Create a temp variable (almost like an index i)
+ // Copy in the address from head and save it
+ Node current = head;
+
+ while (current != null){
+ // print the value inside the node
+ System.out.println(current.data);
+
+ // go to the next node
+ current = current.next;
+ }
+ }
+
+ @Override
+ public String toString(){
+ if (head == null) {
+ // If list is empty, indicate with []
+ return "[]";
+ }
+
+ // If I got here, the list is not empty for sure
+ StringBuilder sb = new StringBuilder();
+ sb.append("[");
+
+ Node current = head;
+ while (current.next != null){
+ sb.append(current.data);
+ sb.append(", ");
+
+ current = current.next;
+ }
+
+ // add the last node
+ sb.append(current.data);
+ sb.append("]");
+ return sb.toString();
+ }
+
+
+ // Nested or inner class (helper class)
+ public class LinkedIntListIterator implements Iterator{
+ private Node current; // holds address of current node
+
+ public LinkedIntListIterator(){
+ // Start the current position at the first node in the list
+ current = head;
+ }
+
+ @Override
+ public boolean hasNext() {
+ return current != null;
+ }
+
+ @Override
+ public Integer next() {
+ int result = current.data;
+ current = current.next;
+ return result;
+ }
+ }
+}
diff --git a/src/LinkedIntListTest.java b/src/LinkedIntListTest.java
new file mode 100644
index 0000000..852d7c3
--- /dev/null
+++ b/src/LinkedIntListTest.java
@@ -0,0 +1,452 @@
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+class LinkedIntListTest {
+
+ // addFront() tests
+
+
+ @Test
+ void addFrontWithEmptyList() {
+ LinkedIntList theList = new LinkedIntList();
+ theList.addFront(25);
+ assertEquals(theList.get(0), 25);
+ }
+
+ @Test
+ void addFrontWithSingleItemList() {
+ LinkedIntList theList = new LinkedIntList();
+ theList.addFront(40);
+ theList.addFront(4);
+ assertEquals(theList.get(0), 4);
+ }
+
+ @Test
+ void addFrontWithMultiItemList() {
+ LinkedIntList theList = new LinkedIntList();
+ theList.addFront(25);
+ theList.addFront(40);
+ theList.addFront(4);
+ theList.addFront(88);
+ assertEquals(theList.get(0), 88);
+ }
+
+
+
+ // addBack() tests
+
+
+
+ @Test
+ void addBackWithEmptyList() {
+ LinkedIntList theList = new LinkedIntList();
+ theList.addBack(25);
+ assertEquals(theList.get(0), 25);
+ }
+
+ @Test
+ void addBackWithSingleItemList() {
+ LinkedIntList theList = new LinkedIntList();
+ theList.addBack(50);
+ theList.addBack(30);
+ assertEquals(theList.get(theList.size()-1), 30);
+ }
+
+ @Test
+ void addBackWithMultiItemList() {
+ LinkedIntList theList = new LinkedIntList();
+ theList.addBack(50);
+ theList.addBack(30);
+ theList.addBack(23);
+ theList.addBack(88);
+ assertEquals(theList.get(theList.size()-1), 88);
+ }
+
+
+
+ // add() Tests
+
+
+ @org.junit.jupiter.api.Test
+ void addWithEmptyList() {
+ LinkedIntList theList = new LinkedIntList();
+
+ theList.add(0, 42);
+ assertEquals(theList.get(0), 42);
+ }
+ @org.junit.jupiter.api.Test
+ void addWithNonEmptyListToMiddle() {
+ LinkedIntList theList = new LinkedIntList();
+ theList.addFront(50);
+ theList.addFront(24);
+ theList.addFront(15);
+ theList.addFront(50);
+ theList.addFront(22);
+ theList.addFront(15);
+
+ theList.add(2, 15);
+ assertEquals(theList.get(2), 15);
+ }
+
+ @org.junit.jupiter.api.Test
+ void addWithNonEmptyListToBack() {
+ LinkedIntList theList = new LinkedIntList();
+ theList.addBack(50);
+ theList.addBack(24);
+ theList.addBack(15);
+ theList.addBack(50);
+ theList.addBack(22);
+ theList.addBack(15);
+
+ theList.add(theList.size()-1, 15);
+ assertEquals(theList.get(theList.size()-1), 15);
+ }
+ @org.junit.jupiter.api.Test
+ void addWithIndexOutOfRange() {
+ LinkedIntList theList = new LinkedIntList();
+
+ theList.addFront(42);
+ theList.addFront(55);
+ theList.addFront(80);
+
+ assertThrows(IndexOutOfBoundsException.class, ()->{theList.add(5, 2);});
+ }
+
+
+
+ // removeFront() Tests
+
+
+ @org.junit.jupiter.api.Test
+ void removeFront() {
+ LinkedIntList theList = new LinkedIntList();
+
+ theList.addFront(42);
+ theList.addFront(55);
+ theList.addFront(72);
+ theList.addFront(80);
+ theList.addFront(24);
+ theList.removeFront();
+ assertEquals(theList.get(0), 80);
+ }
+
+ @org.junit.jupiter.api.Test
+ void removeFrontMultipleTimes() {
+ LinkedIntList theList = new LinkedIntList();
+
+ theList.addFront(42);
+ theList.addFront(55);
+ theList.addFront(72);
+ theList.addFront(80);
+ theList.addFront(24);
+ theList.removeFront();
+ theList.removeFront();
+ theList.removeFront();
+ theList.removeFront();
+ assertEquals(theList.get(0), 42);
+ }
+
+ @org.junit.jupiter.api.Test
+ void removeFrontEmptyList() {
+ LinkedIntList theList = new LinkedIntList();
+
+ assertThrows(IllegalStateException.class, theList::removeFront);
+ }
+
+
+
+ // removeBack() Tests
+
+
+ @org.junit.jupiter.api.Test
+ void removeBackFromEmptyList() {
+ LinkedIntList theList = new LinkedIntList();
+
+ assertThrows(IllegalStateException.class, theList::removeBack);
+ }
+
+ @org.junit.jupiter.api.Test
+ void removeBackFromSingleItemList() {
+ LinkedIntList theList = new LinkedIntList();
+
+ theList.addBack(50);
+ theList.removeBack();
+ assertEquals(theList.size(), 0);
+ }
+
+ @org.junit.jupiter.api.Test
+ void removeBackFromListOf10() {
+ LinkedIntList theList = new LinkedIntList();
+
+ // Fill list with 10 items [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
+ for(int i=0; i < 10; i++){
+ theList.addBack(i);
+ }
+
+ // Remove the item from the back
+ theList.removeBack();
+
+ String out = theList.toString();
+ assertEquals(out, "[0, 1, 2, 3, 4, 5, 6, 7, 8]");
+ }
+
+
+
+ // remove() Tests
+
+
+ @org.junit.jupiter.api.Test
+ void removeFromMiddle() {
+ LinkedIntList theList = new LinkedIntList();
+ // Add 100 numbers to the list
+ for(int i = 0; i < 100; i++){
+ theList.addBack(i);
+ }
+ assertEquals(theList.remove(5), 5);
+ }
+
+ @org.junit.jupiter.api.Test
+ void removeFromBeginning() {
+ LinkedIntList theList = new LinkedIntList();
+ // Add 100 numbers to the list
+ for(int i = 0; i < 100; i++){
+ theList.addBack(i);
+ }
+ assertEquals(theList.remove(0), 0);
+ }
+
+ @org.junit.jupiter.api.Test
+ void removeFromEnd() {
+ LinkedIntList theList = new LinkedIntList();
+ // Add 100 numbers to the list
+ for(int i = 0; i < 100; i++){
+ theList.addBack(i);
+ }
+ assertEquals(theList.remove(theList.size()-1), 99);
+ }
+
+
+
+ // get() Tests
+
+
+ @org.junit.jupiter.api.Test
+ void getFromEmptyList() {
+ LinkedIntList theList = new LinkedIntList();
+ assertThrows(IndexOutOfBoundsException.class, ()->{
+ theList.get(0);
+ });
+ }
+
+ @org.junit.jupiter.api.Test
+ void getFromSingleItemList() {
+ LinkedIntList theList = new LinkedIntList();
+ theList.addFront(50);
+ assertEquals(theList.get(0), 50);
+ }
+
+ @org.junit.jupiter.api.Test
+ void getFromMultiItemList() {
+ LinkedIntList theList = new LinkedIntList();
+ theList.addFront(50);
+ theList.addFront(22);
+ theList.addBack(78);
+ theList.addBack(45);
+ theList.addBack(14);
+ assertEquals(theList.get(2), 78);
+ }
+
+ @org.junit.jupiter.api.Test
+ void getFromBack() {
+ LinkedIntList theList = new LinkedIntList();
+ theList.addFront(50);
+ theList.addFront(22);
+ theList.addFront(15);
+ theList.addFront(66);
+ assertEquals(theList.get(theList.size()-1), 50);
+ }
+
+
+
+ // contains() Tests
+
+
+ @org.junit.jupiter.api.Test
+ void containsWithEmptyList() {
+ LinkedIntList theList = new LinkedIntList();
+ assertFalse(theList.contains(5));
+ }
+
+ @org.junit.jupiter.api.Test
+ void containsWithSingleItem() {
+ LinkedIntList theList = new LinkedIntList();
+ theList.addFront(5);
+ assertTrue(theList.contains(5));
+ }
+
+ @org.junit.jupiter.api.Test
+ void containsWithMultiItem() {
+ LinkedIntList theList = new LinkedIntList();
+ theList.addFront(5);
+ theList.addFront(10);
+ theList.addFront(15);
+ theList.addFront(20);
+ assertTrue(theList.contains(15));
+ }
+
+
+ // indexOf() Tests
+
+
+ @org.junit.jupiter.api.Test
+ void indexOfEmptyList() {
+ LinkedIntList theList = new LinkedIntList();
+ assertEquals(theList.indexOf(0), -1);
+ }
+
+ @org.junit.jupiter.api.Test
+ void indexOfSingleItem() {
+ LinkedIntList theList = new LinkedIntList();
+ theList.addFront(10);
+ assertEquals(theList.indexOf(10), 0);
+ }
+
+ @org.junit.jupiter.api.Test
+ void indexOfFullList() {
+ LinkedIntList theList = new LinkedIntList();
+ theList.addFront(10);
+ theList.addFront(22);
+ theList.addFront(36);
+ theList.addFront(78);
+ theList.addFront(49);
+ theList.addFront(99);
+ assertEquals(theList.indexOf(78), 2);
+ }
+
+ @org.junit.jupiter.api.Test
+ void indexOfItemAtEnd() {
+ LinkedIntList theList = new LinkedIntList();
+ theList.addFront(10);
+ theList.addFront(56);
+ theList.addFront(99);
+ theList.addFront(28);
+ theList.addFront(75);
+ theList.addFront(73);
+ theList.addFront(58);
+ assertEquals(theList.indexOf(10), theList.size()-1);
+ }
+
+
+
+ // isEmpty() Tests
+
+
+ @org.junit.jupiter.api.Test
+ void isEmptyWithNoItems() {
+ LinkedIntList theList = new LinkedIntList();
+
+ assertTrue(theList.isEmpty());
+ }
+
+ @org.junit.jupiter.api.Test
+ void isEmptyWithSingleItem() {
+ LinkedIntList theList = new LinkedIntList();
+ theList.addFront(10);
+
+ assertFalse(theList.isEmpty());
+ }
+
+ @org.junit.jupiter.api.Test
+ void isEmptyWithMultipleItems() {
+ LinkedIntList theList = new LinkedIntList();
+ theList.addFront(10);
+ theList.addFront(22);
+ theList.addFront(76);
+ theList.addFront(48);
+ theList.addFront(90);
+
+ assertFalse(theList.isEmpty());
+ }
+
+ @org.junit.jupiter.api.Test
+ void isEmptyAfterRemoval() {
+ LinkedIntList theList = new LinkedIntList();
+ theList.addFront(10);
+ theList.addFront(22);
+ theList.removeFront();
+ theList.removeFront();
+
+ assertTrue(theList.isEmpty());
+ }
+
+
+
+ // size() Tests
+
+
+ @org.junit.jupiter.api.Test
+ void sizeWhileEmpty() {
+ LinkedIntList theList = new LinkedIntList();
+
+ assertEquals(theList.size(), 0);
+ }
+
+ @org.junit.jupiter.api.Test
+ void sizeWithSingleItem() {
+ LinkedIntList theList = new LinkedIntList();
+
+ theList.addFront(55);
+
+ assertEquals(theList.size(), 1);
+ }
+
+ @org.junit.jupiter.api.Test
+ void sizeWithMultipleItems() {
+ LinkedIntList theList = new LinkedIntList();
+
+ for(int i=0; i< 100; i++){
+ theList.addBack(i);
+ }
+
+ assertEquals(theList.size(), 100);
+ }
+
+
+
+ // clear() Tests
+
+
+ @org.junit.jupiter.api.Test
+ void clearWithItemsInList() {
+ LinkedIntList theList = new LinkedIntList();
+
+ theList.addFront(5);
+ theList.addFront(50);
+ theList.addFront(24);
+
+ theList.clear();
+ assertEquals(theList.size(), 0);
+ }
+
+ @org.junit.jupiter.api.Test
+ void clearWithEmptyList() {
+ LinkedIntList theList = new LinkedIntList();
+
+ theList.clear();
+ assertEquals(theList.size(), 0);
+ }
+
+ @org.junit.jupiter.api.Test
+ void clearAfterAddThenRemoveList() {
+ LinkedIntList theList = new LinkedIntList();
+
+ theList.addFront(5);
+ theList.addFront(50);
+ theList.removeFront();
+ theList.removeFront();
+
+ theList.clear();
+ assertEquals(theList.size(), 0);
+ }
+}
\ No newline at end of file
diff --git a/src/Main.java b/src/Main.java
index 930198c..ba58c91 100644
--- a/src/Main.java
+++ b/src/Main.java
@@ -1,15 +1,117 @@
-//TIP To Run code, press or
-// click the icon in the gutter.
+import java.util.Iterator;
+
public class Main {
public static void main(String[] args) {
- //TIP Press with your caret at the highlighted text
- // to see how IntelliJ IDEA suggests fixing it.
- System.out.printf("Hello and welcome!");
-
- for (int i = 1; i <= 5; i++) {
- //TIP Press to start debugging your code. We have set one breakpoint
- // for you, but you can always add more by pressing .
- System.out.println("i = " + i);
+ IntList list1 = new ArrayIntList();
+ IntList list2 = new LinkedIntList();
+
+ System.out.println("------------------ArrayIntList-------------------");
+ System.out.println(list1.indexOf(97));
+
+ // Add 3 ints to the back of the list
+ list1.addBack(42);
+ list1.addBack(82);
+ list1.addBack(97);
+ list1.addBack(42);
+ list1.addBack(82);
+ list1.addBack(97);
+
+
+ list1.addFront(99);
+
+ System.out.println(list1);
+
+ list1.add(6, 20);
+
+ System.out.println(list1);
+
+
+ System.out.println(list1.indexOf(88));
+
+ System.out.println(list1);
+
+
+ Iterator itr = list1.iterator();
+ while (itr.hasNext()){
+ int value = itr.next();
+ System.out.println(value);
+ }
+
+ // -----------------------
+ // Linked List Short Test
+ // -----------------------
+
+
+
+ System.out.println("------------------LinkedIntList-------------------");
+
+ System.out.println(list2.contains(22));
+
+ list2.removeBack();
+ System.out.println(list2);
+
+ list2.addFront(42);
+ System.out.println(list2);
+
+ list2.removeBack();
+ System.out.println(list2);
+
+ list2.addFront(82);
+ list2.addFront(97);
+
+ list2.addBack(50);
+ list2.addBack(23);
+
+ list2.addFront(30);
+
+ System.out.println(list2);
+
+ for(int value: list2){
+ System.out.println(value);
}
+
+ list2.removeBack();
+ System.out.println(list2);
+
+ list2.removeFront();
+ System.out.println(list2);
+ list2.removeFront();
+ System.out.println(list2);
+ list2.removeFront();
+ System.out.println(list2);
+ list2.removeFront();
+ System.out.println(list2);
+
+ list2 = new LinkedIntList();
+
+ list2.add(0, 10);
+ System.out.println(list2);
+
+ list2.addFront(2);
+ list2.addFront(5);
+ list2.addFront(30);
+ list2.addFront(92);
+ System.out.println("94: " + list2);
+ list2.add(3, 55);
+ System.out.println("96: " + list2);
+ list2.add(5, 75);
+ System.out.println("98: " + list2);
+ System.out.println(list2.size()-1);
+ list2.add(list2.size(), 33);
+ System.out.println("100: " + list2);
+
+ //System.out.println(list2.contains(22));
+ //System.out.println(list2.get(0));
+
+ System.out.println("-------------------");
+ System.out.println(list2);
+ System.out.println(list2.remove(4));
+
+ System.out.println("-------------------");
+ System.out.println(list2);
+ System.out.println(list2.indexOf(1));
+
+ //list2.add(1, 20);
+ //System.out.println(list2);
}
}
\ No newline at end of file