diff --git a/IntListReview.iml b/IntListReview.iml index c90834f..0f07f6c 100644 --- a/IntListReview.iml +++ b/IntListReview.iml @@ -4,8 +4,25 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/ArrayIntList.java b/src/ArrayIntList.java new file mode 100644 index 0000000..c0ce054 --- /dev/null +++ b/src/ArrayIntList.java @@ -0,0 +1,297 @@ +import java.util.Iterator; +import java.util.NoSuchElementException; + +public class ArrayIntList implements IntList { + + //fields: + private int size; + private int[] buffer; + + public ArrayIntList() + { + //initialize my fields + size = 0; + buffer = new int[10]; + } + + /** + * 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. + * + * @param value value to be inserted + */ + @Override + public void addFront(int value) { + if(size == buffer.length) + { + resize(size * 2); + } + + for(int i = size; i >= 1; i--) + { + buffer[i] = buffer[i-1]; + } + buffer[0] = value; + size++; + } + + /** + * Appends (inserts) the specified value at the back of the list (at index size()-1). + * + * @param value value to be inserted + */ + @Override + public void addBack(int value) { + //TODO: check to see if we are full - if so, we need to create a larger buffer + if(size == buffer.length) + { + resize(size * 2); + } + + 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. + * + * @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 || index < 0) + { + throw new IndexOutOfBoundsException("Invalid index"); + } + if(size == buffer.length) + { + resize(size * 2); + } + if(index == size) + { + buffer[index] = value; + } + else { + 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. + */ + @Override + public void removeFront() { + if(!isEmpty()) + { + for (int i = 0; i <= size - 2; i++) { + buffer[i] = buffer[i + 1]; + } + buffer[size - 1] = 0; + size--; + } + } + + /** + * Removes the value located at the back of the list + * (at index size()-1), if it is present. + */ + @Override + public void removeBack() { + if(!isEmpty()) + { + buffer[size-1] = 0; + size--; + return; + } + throw new NoSuchElementException("There are no elements to remove!"); + } + + /** + * 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) { + //check to see if index is valid + if(index >= size || index < 0) + { + throw new IndexOutOfBoundsException("Invalid index"); + } + // save a copy of the value to be returned later + int removedValue = buffer[index]; + + //shift values to the left + for (int i = index; i < size; i++) { + buffer[i] = buffer[i+1]; + } + //remove the final index value + buffer[size - 1] = 0; + //decrement size + size--; + //return the removed value + return removedValue; + } + + /** + * Returns the value at the specified position in the list. + * + * @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) + { + throw new IndexOutOfBoundsException(); + } + return buffer[index]; + } + + /** + * 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) { + 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. + * + * @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() { + buffer = new int[buffer.length]; + size = 0; + } + + private void resize(int newSize) + { + int[] newBuffer = new int[newSize]; + + for (int i = 0; i < size; i++) { + newBuffer[i] = buffer[i]; + } + //set the new space into the buffer + buffer = newBuffer; + + //the old space is no longer "pointed to" and will eventually + //be cleaned up by the garbage collector + } + + /** + * Returns an iterator over elements of type {@code T}. + * + * @return an Iterator. + */ + @Override + public Iterator iterator() { + return new IntListIterator(); + } + + //create a private helper Iterator class + private class IntListIterator implements Iterator{ + //private fields + private int i; + + private IntListIterator(){ + i = 0; + } + + + /** + * Returns {@code true} if the iteration has more elements. + * (In other words, returns {@code true} if {@link #next} would + * return an element rather than throwing an exception.) + * + * @return {@code true} if the iteration has more elements + */ + @Override + public boolean hasNext() { + return i < size; + } + + /** + * Returns the next element in the iteration. + * + * @return the next element in the iteration + * @throws NoSuchElementException if the iteration has no more elements + */ + @Override + public Integer next() { + if(i >= size) + { + throw new NoSuchElementException("i is out of bounds"); + } + int currentValue = buffer[i]; + i++; + return currentValue; + } + } +} diff --git a/src/DoublyLinkedIntList.java b/src/DoublyLinkedIntList.java new file mode 100644 index 0000000..e8a6bdb --- /dev/null +++ b/src/DoublyLinkedIntList.java @@ -0,0 +1,320 @@ +import java.util.Iterator; + +public class DoublyLinkedIntList implements IntList{ + // private fields + private class Node { + int data; + Node next; // address of the node "after" this one in line + Node prev; // address of the node "before" this one in line + + public Node() + { + next = null; + prev = null; + } + } + + private Node pre; + private Node post; + private int size; + + //constructor + public DoublyLinkedIntList() { + // an empty list has 2 sentinel (dummy) nodes that serve as bookends + pre = new Node(); + post = new Node(); + pre.next = post; + post.prev = pre; + 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. + * + * @param value value to be inserted + */ + @Override + public void addFront(int value) { + Node theFirstOne = pre.next; + // set up my new node and fill it out (data, prev, next) + Node theNewOne = new Node(); + theNewOne.data = value; + theNewOne.prev = pre; + theNewOne.next = theFirstOne; + // go to the front of the list's sentinel, and update it's next + pre.next = theNewOne; + // go to the node after the new one, and update it's prev + theFirstOne.prev = theNewOne; + // increment size + size++; + } + + /** + * Appends (inserts) the specified value at the back of the list (at index size()-1). + * + * @param value value to be inserted + */ + @Override + public void addBack(int value) { + Node theLastOne = post.prev; + // set up my new node and fill it out (data, prev, next) + Node theNewOne = new Node(); + theNewOne.data = value; + theNewOne.next = post; + theNewOne.prev = theLastOne; + // go to the end of the list's sentinel, and update it's prev + post.prev = theNewOne; + // go to the node before the new one, and update it's next + theLastOne.next = theNewOne; + // increment size + 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(size < index) + { + System.out.println("Index out of bounds!"); + return; + } + if(size == 0) + { + Node theNewOne = new Node(); + theNewOne.data = value; + theNewOne.next = post; + theNewOne.prev = pre; + pre.next = theNewOne; + post.prev = theNewOne; + size++; + return; + } + Node current = pre; + for (int i = 0; i < index; i++) { + current = current.next; + } + Node theNewOne = new Node(); + theNewOne.data = value; + theNewOne.next = current.next; + theNewOne.next.prev = theNewOne; + current.next = theNewOne; + theNewOne.prev = current; + 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) + { + // set up a temporary variable for convenience + Node theOneToRemove = pre.next; + theOneToRemove.next.prev = pre; + pre.next = theOneToRemove.next; + // decrement size + 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) + { + // set up a temporary variable for convenience + Node theOneToRemove = post.prev; + theOneToRemove.prev.next = post; + post.prev = theOneToRemove.prev; + /* + if you do not want to create a temp variable: + post.prev = post.prev.prev; + post.prev.prev.next = post; + */ + + 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) { + // check if index is valid + if(index >= size || index < 0) + { + throw new IndexOutOfBoundsException("Invalid index given!"); + } + // set midpoint to check which sentinel value is closer + int mid = size / 2; + // check if index is closer to pre + if(index <= mid) + { + Node current = pre.next; + for (int i = 0; i < index; i++) { + current = current.next; + } + // save value to be returned + int valueToBeReturned = current.data; + // move prev.next to next Node + current.prev.next = current.next; + // move next.prev to prev Node + current.next.prev = current.prev; + size--; + return valueToBeReturned; + } + // else, index is closer to post + Node current = post.prev; + for (int i = size-1; i > index; i--) { + current = current.prev; + } + // save value to be returned + int valueToBeReturned = current.data; + // move prev.next to next Node + current.prev.next = current.next; + // move next.prev to prev Node + current.next.prev = current.prev; + size--; + return valueToBeReturned; + } + + /** + * Returns the value at the specified position in the list. + * + * @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) { + // check if index is valid + if(index >= size || index < 0) + { + throw new IndexOutOfBoundsException("Invalid index given!"); + } + // set midpoint to check which sentinel value is closer + int mid = size / 2; + // check if index is closer to pre + if(index <= mid) + { + Node current = pre.next; + for (int i = 0; i < index; i++) { + current = current.next; + } + return current.data; + } + // else, index is closer to post + Node current = post.prev; + for (int i = size-1; i > index; i--) { + current = current.prev; + } + return current.data; + } + + /** + * 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 = pre; + while(current != post) + { + 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) { + Node current = pre.next; + int indexCounter = 0; + while(current != post) + { + if(current.data == value) + { + return indexCounter; + } + current = current.next; + indexCounter++; + } + 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() { + pre.next = post; + post.prev = pre; + size = 0; + } + + /** + * Returns an iterator over elements of type {@code T}. + * + * @return an Iterator. + */ + @Override + public Iterator iterator() { + return null; + } +} diff --git a/src/LinkedIntList.java b/src/LinkedIntList.java new file mode 100644 index 0000000..839d6cb --- /dev/null +++ b/src/LinkedIntList.java @@ -0,0 +1,371 @@ +import java.util.Iterator; +import java.util.NoSuchElementException; + +public class LinkedIntList implements IntList{ + + // define what a node is + private class Node { + int data; + Node next; + } + + + // set up the head + private Node head; + + //set up the size field + private int size; + + // add a constructor to initialize the fields + 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. + * + * @param value value to be inserted + */ + @Override + public void addFront(int value) { + Node newOne = new Node(); + newOne.data = value; + if(head == null) + { + // the list is currently empty + newOne.next = null; + head = newOne; + size++; + return; + } + // the list currently has some nodes in it + newOne.next = head; + head = newOne; + size++; + } + + /** + * Appends (inserts) the specified value at the back of the list (at index size()-1). + * + * @param value value to be inserted + */ + @Override + public void addBack(int value) { + Node newOne = new Node(); + newOne.data = value; + if(head == null) + { + // the list is currently empty + newOne.next = null; + head = newOne; + size++; + return; + } + // the list currently has some nodes in it + Node current = head; + while(current.next != null) + { + current = current.next; + } + current.next = newOne; + 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) { + // throw exception if index given is out of bounds + if(index > size || index < 0) + { + throw new IndexOutOfBoundsException("Invalid index given!"); + } + if(head == null) + { + head = new Node(); + head.data = value; + head.next = null; + size++; + return; + } + // current Node to keep track of index + Node current = head; + // create a new Node + Node theNewOne = new Node(); + // set the new Nodes value + theNewOne.data = value; + // check if index is at the front of the LinkedList + if(index == 0) + { + theNewOne.next = head; + head = theNewOne; + size++; + return; + } + // check if index is at the end of the LinkedList + if(index == size()) + { + // loop to end of the list + while(current.next != null) + { + current = current.next; + } + // add the new Node + current.next = theNewOne; + size++; + return; + } + // else, for loop that stops one before new indexed Node + for (int i = 0; i < index-1; i++) { + current = current.next; + } + // save the old Node from that index so we can move it forward one space + Node nodeAfterAdded = current.next; + // put the new Node in current.next position + current.next = theNewOne; + // move current forward one + current = current.next; + // set the previous index Node forward one index position (e.g. index 3 Node would now become index 4) + current.next = nodeAfterAdded; + 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) + { + head = head.next; + 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() <= 1) + { + head = null; + size --; + return; + } + Node current = head; + for (int i = 0; i < size()-2; i++) { + current = current.next; + } + current.next = 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) { + // check if index is invalid + if(index >= size() || index < 0) + { + throw new IndexOutOfBoundsException("Invalid index given!"); + } + if(index == 0) + { + int dataToBeRemoved = head.data; + head.data = 0; + head = head.next; + size--; + return dataToBeRemoved; + } + // current Node to iterate through LinkedList + Node current = head; + // loop until one Node before our index + for (int i = 0; i < index-1; i++) { + current = current.next; + } + // save our value that will be removed + int dataToBeRemoved = current.next.data; + // check if there are two Nodes ahead for easy shifting + if(size()-index > 1) + { + // move current.next an additional space forward + current.next = current.next.next; + size--; + return dataToBeRemoved; + } + // else, remove the next Node (there are no Nodes ahead of our index) + current.next = null; + size--; + return dataToBeRemoved; + } + + /** + * Returns the value at the specified position in the list. + * + * @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 || index < 0) + { + throw new IndexOutOfBoundsException("Invalid index given!"); + } + Node current = head; + for (int i = 0; i < index; i++) { + current = current.next; + } + return current.data; + } + + /** + * 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) { + Node current = head; + int nodeCounter = 0; + while(current != null) + { + if(current.data == value) + { + return nodeCounter; + } + current = current.next; + nodeCounter++; + } + 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 = new Node(); + head.data = 0; + head.next = null; + size = 0; + } + + /** + * Returns an iterator over elements of type {@code T}. + * + * @return an Iterator. + */ + @Override + public Iterator iterator() { + return new SinglyLinkedIterator(); + } + + // helper class/type that defines how the iterator works + private class SinglyLinkedIterator implements Iterator { + private Node current; + + public SinglyLinkedIterator() { + current = head; + } + + + /** + * Returns {@code true} if the iteration has more elements. + * (In other words, returns {@code true} if {@link #next} would + * return an element rather than throwing an exception.) + * + * @return {@code true} if the iteration has more elements + */ + @Override + public boolean hasNext() { + if(current != null) + { + return true; + } + return false; + } + + /** + * Returns the next element in the iteration. + * + * @return the next element in the iteration + * @throws NoSuchElementException if the iteration has no more elements + */ + @Override + public Integer next() { + if(current == null) + { + throw new NoSuchElementException("There is no next element!"); + } + int item = current.data; + current = current.next; + return item; + } + } +} diff --git a/src/Main.java b/src/Main.java index 930198c..e23918b 100644 --- a/src/Main.java +++ b/src/Main.java @@ -11,5 +11,19 @@ public static void main(String[] args) { // for you, but you can always add more by pressing . System.out.println("i = " + i); } + + IntList firstList; + + ArrayIntList secondList = new ArrayIntList(); + + IntList thirdList = new ArrayIntList(); + thirdList.addFront(15); + thirdList.addFront(1); + thirdList.addFront(22); + + for(int value: thirdList) + { + System.out.println(value); + } } } \ No newline at end of file diff --git a/tests/ArrayIntListTest.java b/tests/ArrayIntListTest.java new file mode 100644 index 0000000..3c7ff99 --- /dev/null +++ b/tests/ArrayIntListTest.java @@ -0,0 +1,184 @@ +import static org.junit.jupiter.api.Assertions.*; + +class ArrayIntListTest { + @org.junit.jupiter.api.Test + void addFront() { + ArrayIntList list = new ArrayIntList(); // new list + list.addFront(6); // add 6 to front of empty list + assertEquals(6, list.get(0)); + list.addFront(10); // add 10 to front of list with only 1 item + assertEquals(10, list.get(0)); + list.addFront(20); // add 20 to front of list with more than 1 item + assertEquals(20, list.get(0)); + for (int i = 0; i < 7; i++) { + list.addFront(1); // fill up our buffer + } + list.addFront(9); // add 9 to front of full list, testing resize works + assertEquals(9, list.get(0)); + } + + @org.junit.jupiter.api.Test + void addBack() { + ArrayIntList list = new ArrayIntList(); // new list + list.addBack(6); // add 6 to back of empty list + assertEquals(6, list.get(list.size()-1)); + list.addBack(10); // add 10 to back of list with only 1 item + assertEquals(10, list.get(list.size()-1)); + list.addBack(20); // add 20 to back of list with more than 1 item + assertEquals(20, list.get(list.size()-1)); + for (int i = 0; i < 7; i++) { + list.addBack(1); // fill up our buffer + } + list.addBack(9); // add 9 to back of full list, testing resize works + assertEquals(9, list.get(list.size()-1)); + } + + @org.junit.jupiter.api.Test + void add() { + ArrayIntList list = new ArrayIntList(); // new list + list.add(0, 6); // add 6 at index 0 + assertEquals(6, list.get(0)); + list.add(1, 10); // add 10 at index 1 + assertEquals(10, list.get(1)); + list.add(2, 2); // add 2 at index 2 + assertEquals(2, list.get(2)); + list.add(1, 5); // add 5 at index 1 (moving our previous index 1 over) + assertEquals(5, list.get(1)); + assertEquals(10, list.get(2)); // test index 2 has shifted over value previously in index 1 + } + + @org.junit.jupiter.api.Test + void removeFront() { + ArrayIntList list = new ArrayIntList(); // new list + list.addBack(12); // Add first value + assertEquals(1, list.size()); // check size = 1 + list.removeFront(); // remove our only item from the front + assertEquals(0, list.size()); // check size = 0 + list.addBack(17); + list.addBack(21); + list.addBack(33); // add 3 values + assertEquals(17, list.get(0)); // check front value is 17 + list.removeFront(); // remove 17 from front + assertEquals(21, list.get(0)); // check new front value is 21 + list.removeFront(); // remove 21 from front + assertEquals(33, list.get(0)); // check new front value is 33 + list.removeFront(); // remove 33 from front + assertEquals(0, list.size()); // check size = 0 + } + + @org.junit.jupiter.api.Test + void removeBack() { + ArrayIntList list = new ArrayIntList(); // new list + list.addFront(12); + assertEquals(1, list.size()); // check size = 1 + list.removeBack(); // remove our only item from the back + assertEquals(0, list.size()); // check size = 0 + list.addFront(88); + list.addFront(77); + list.addFront(66); + assertEquals(88, list.get(list.size()-1)); // check front value is 17 + list.removeBack(); // remove 17 from front + assertEquals(77, list.get(list.size()-1)); // check new front value is 21 + list.removeBack(); // remove 21 from front + assertEquals(66, list.get(list.size()-1)); // check new front value is 33 + list.removeBack(); // remove 33 from front + assertEquals(0, list.size()); // check size = 0 + } + + @org.junit.jupiter.api.Test + void remove() { + ArrayIntList list = new ArrayIntList(); // new list + // add test values + list.add(0, 12); + list.add(1, 100); + list.add(2, 55); + list.add(3, 19); + list.add(4, 5); + + assertEquals(12, list.remove(0)); // remove index 0 (12) + assertEquals(100, list.get(0)); // get new index 0 (100) + assertEquals(19, list.remove(2)); // remove index 2 (now 19) + assertEquals(5, list.get(2)); // get new index 2 (5) + assertEquals(55, list.remove(1)); // remove index 1 (now 55) + assertEquals(100, list.get(0)); // get new index 0 (100) + assertEquals(100, list.remove(0)); // remove index 0 (100) + assertEquals(5, list.get(0)); // get new index 0 (5) + assertEquals(5, list.remove(0)); // remove index 0 (5) + } + + @org.junit.jupiter.api.Test + void get() { + ArrayIntList list = new ArrayIntList(); // new list + list.addFront(5); + list.addFront(9); + list.addFront(23); + list.addFront(11); + list.addFront(16); // add values to front + assertEquals(16, list.get(0)); // test getting index 0 + assertEquals(5, list.get(4)); // test getting index 4 + assertEquals(23, list.get(2)); // test getting index 2 + } + + @org.junit.jupiter.api.Test + void contains() { + ArrayIntList list = new ArrayIntList(); // new list + assertEquals(false, list.contains(0)); // check if empty list contains 0 + list.addFront(7); + list.addFront(15); + list.addFront(33); + list.addFront(45); // add values to front + assertEquals(true, list.contains(7)); // check if list contains 7 + assertEquals(false, list.contains(13)); // check if list contains 13 + assertEquals(true, list.contains(45)); // check if list contains 45 + assertEquals(false, list.contains(22)); // check if list contains 22 + } + + @org.junit.jupiter.api.Test + void indexOf() { + ArrayIntList list = new ArrayIntList(); // new list + list.addFront(3); + assertEquals(0, list.indexOf(3)); // check for index of 3 + assertEquals(-1, list.indexOf(5)); // check for index of 5 (doesn't exist) + for (int i = 0; i < 9; i++) { + list.addBack(8); + } + assertEquals(1, list.indexOf(8)); // check for first index of 8 + } + + @org.junit.jupiter.api.Test + void isEmpty() { + ArrayIntList list = new ArrayIntList(); // new list + assertEquals(true, list.isEmpty()); // testing isEmpty() on empty list + list.addFront(5); + assertEquals(false, list.isEmpty()); // testing isEmpty() on list with 1 item + for (int i = 0; i < 9; i++) { + list.addFront(10); + } + assertEquals(false, list.isEmpty()); // testing isEmpty() on list with 10 items + } + + @org.junit.jupiter.api.Test + void size() { + ArrayIntList list = new ArrayIntList(); // new list + assertEquals(0, list.size()); // testing for 0 items + list.addFront(10); + assertEquals(1, list.size()); // testing for 1 item + for (int i = 0; i < 9; i++) { + list.addFront(1); + } + assertEquals(10, list.size()); // testing for 10 items (full buffer) + } + + @org.junit.jupiter.api.Test + void clear() { + ArrayIntList list = new ArrayIntList(); // new list + list.addFront(3); + list.clear(); // clear list + assertEquals(0, list.size()); // check size after clear + for (int i = 0; i < 10; i++) { + list.addFront(5); + } + list.clear(); // clear list + assertEquals(0, list.size()); // check size after clear + } +} \ No newline at end of file diff --git a/tests/DoublyLinkedIntListTest.java b/tests/DoublyLinkedIntListTest.java new file mode 100644 index 0000000..ac57adb --- /dev/null +++ b/tests/DoublyLinkedIntListTest.java @@ -0,0 +1,214 @@ +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +class DoublyLinkedIntListTest { + + @Test + void addFront() { + DoublyLinkedIntList list = new DoublyLinkedIntList(); // empty list for testing + assertEquals(0, list.size()); // test by checking size and indices + list.addFront(12); + assertEquals(12, list.get(0)); + list.addFront(45); + assertEquals(45, list.get(0)); + assertEquals(2, list.size()); + } + + @Test + void addBack() { + DoublyLinkedIntList list = new DoublyLinkedIntList(); // empty list for testing + assertEquals(0, list.size()); // test by checking size and indices + list.addBack(12); + assertEquals(12, list.get(list.size()-1)); + list.addBack(45); + assertEquals(45, list.get(list.size()-1)); + assertEquals(2, list.size()); + } + + @Test + void add() { + DoublyLinkedIntList list = new DoublyLinkedIntList(); // empty list for testing + assertEquals(0, list.size()); // test by checking size and indices + list.add(0, 12); + assertEquals(12, list.get(0)); + list.add(1, 45); + assertEquals(45, list.get(1)); + assertEquals(2, list.size()); + list.add(1, 24); + assertEquals(24, list.get(1)); + assertEquals(45, list.get(2)); + assertEquals(3, list.size()); + } + + @Test + void removeFront() { + DoublyLinkedIntList list = new DoublyLinkedIntList(); // empty list for testing + list.addBack(12); + assertEquals(1, list.size()); // test by checking size and indices + list.removeFront(); + list.addBack(44); + list.addBack(32); + list.addBack(19); + list.addBack(87); + assertEquals(4, list.size()); + assertEquals(44, list.get(0)); + list.removeFront(); + assertEquals(3, list.size()); + assertEquals(32, list.get(0)); + list.removeFront(); + assertEquals(2, list.size()); + assertEquals(19, list.get(0)); + list.removeFront(); + assertEquals(1, list.size()); + assertEquals(87, list.get(0)); + list.removeFront(); + assertEquals(0, list.size()); + } + + @Test + void removeBack() { + DoublyLinkedIntList list = new DoublyLinkedIntList(); // empty list for testing + list.addBack(12); + assertEquals(1, list.size()); // test by checking size and indices + list.removeBack(); + assertEquals(0, list.size()); + list.addBack(14); + list.addBack(19); + list.addBack(44); + list.addBack(31); + assertEquals(4, list.size()); + assertEquals(31, list.get(list.size()-1)); + list.removeBack(); + assertEquals(3, list.size()); + assertEquals(44, list.get(list.size()-1)); + list.removeBack(); + assertEquals(2, list.size()); + assertEquals(19, list.get(list.size()-1)); + list.removeBack(); + assertEquals(1, list.size()); + assertEquals(14, list.get(list.size()-1)); + list.removeBack(); + assertEquals(0, list.size()); + } + + @Test + void remove() { + DoublyLinkedIntList list = new DoublyLinkedIntList(); // empty list for testing + list.addBack(12); + assertEquals(1, list.size()); // test by checking size and indices + list.remove(0); + assertEquals(0, list.size()); + list.addBack(22); + list.addBack(16); + list.addBack(4); + list.addBack(99); + list.addBack(28); + assertEquals(5, list.size()); + assertEquals(16, list.get(1)); + list.remove(1); + assertEquals(4, list.get(1)); + assertEquals(4, list.size()); + list.remove(0); + assertEquals(4, list.get(0)); + assertEquals(3, list.size()); + } + + @Test + void get() { + DoublyLinkedIntList list = new DoublyLinkedIntList(); // empty list for testing + list.addBack(22); // test by adding values + assertEquals(22, list.get(0)); + list.addBack(45); + list.addBack(45); + list.addBack(20); + list.addBack(19); + list.addBack(33); + list.addBack(16); + assertEquals(45, list.get(1)); + assertEquals(45, list.get(2)); + assertEquals(19, list.get(4)); + assertEquals(16, list.get(list.size()-1)); + } + + @Test + void contains() { + DoublyLinkedIntList list = new DoublyLinkedIntList(); // empty list for testing + list.addBack(22); // test by adding values + list.addBack(10); + list.addBack(3); + list.addBack(65); + list.addBack(9); + assertEquals(true, list.contains(3)); + assertEquals(false, list.contains(44)); + assertEquals(true, list.contains(9)); + assertEquals(false, list.contains(900)); + assertEquals(false, list.contains(101)); + assertEquals(true, list.contains(10)); + assertEquals(true, list.contains(22)); + } + + @Test + void indexOf() { + DoublyLinkedIntList list = new DoublyLinkedIntList(); // empty list for testing + list.addBack(22); // test by adding values + list.addBack(44); + list.addBack(68); + list.addBack(31); + list.addBack(11); + list.addBack(22); + assertEquals(0, list.indexOf(22)); + assertEquals(-1, list.indexOf(20)); + assertEquals(3, list.indexOf(31)); + assertEquals(4, list.indexOf(11)); + assertEquals(-1, list.indexOf(2298473)); + } + + @Test + void isEmpty() { + DoublyLinkedIntList list = new DoublyLinkedIntList(); // empty list for testing + assertEquals(true, list.isEmpty()); + list.addFront(12); // test by adding values and clearing the list + assertEquals(false, list.isEmpty()); + list.addFront(14); + list.addFront(16); + list.addFront(19); + assertEquals(false, list.isEmpty()); + list.clear(); + assertEquals(true, list.isEmpty()); + } + + @Test + void size() { + DoublyLinkedIntList list = new DoublyLinkedIntList(); // empty list for testing + assertEquals(0, list.size()); + list.addFront(12); // test by adding and removing values + assertEquals(1, list.size()); + list.addBack(55); + assertEquals(2, list.size()); + list.add(1, 68); + assertEquals(3, list.size()); + list.remove(1); + assertEquals(2, list.size()); + list.removeBack(); + assertEquals(1, list.size()); + list.removeFront(); + assertEquals(0, list.size()); + } + + @Test + void clear() { + DoublyLinkedIntList list = new DoublyLinkedIntList(); // empty list for testing + list.addFront(12); + assertEquals(1, list.size()); // test size for clear() + list.clear(); + assertEquals(0, list.size()); + list.addFront(14); + list.addFront(33); + list.addFront(98); + list.addFront(22); + assertEquals(4, list.size()); + list.clear(); + assertEquals(0, list.size()); + } +} \ No newline at end of file diff --git a/tests/LinkedIntListTest.java b/tests/LinkedIntListTest.java new file mode 100644 index 0000000..bfd3e79 --- /dev/null +++ b/tests/LinkedIntListTest.java @@ -0,0 +1,286 @@ +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +class LinkedIntListTest { + + @Test + void addFront() { + LinkedIntList list = new LinkedIntList(); // new list for testing + // add values to front, check if size has increased by 1 and the value in index 0 is correct + list.addFront(6); + assertEquals(1, list.size()); + assertEquals(6, list.get(0)); + list.addFront(15); + assertEquals(2, list.size()); + assertEquals(15, list.get(0)); + list.addFront(22); + assertEquals(3, list.size()); + assertEquals(22, list.get(0)); + } + + @Test + void addBack() { + LinkedIntList list = new LinkedIntList(); // new list for testing + // add values to back, check if size has increased by 1 and the value in index size()-1 is correct + list.addBack(6); + assertEquals(1, list.size()); + assertEquals(6, list.get(list.size()-1)); + list.addBack(11); + assertEquals(2, list.size()); + assertEquals(11, list.get(list.size()-1)); + list.addBack(43); + assertEquals(3, list.size()); + assertEquals(43, list.get(list.size()-1)); + } + + @Test + void add() { + LinkedIntList list = new LinkedIntList(); // new list for testing + // add index 0, check size incremented and value was added + list.add(0, 4); + assertEquals(1, list.size()); + assertEquals(4, list.get(0)); + // add index 1, check size incremented and value was added + list.add(1, 29); + assertEquals(2, list.size()); + assertEquals(29, list.get(1)); + // add NEW index 1, check size incremented and value was added + list.add(1, 12); + assertEquals(3, list.size()); + assertEquals(12, list.get(1)); + // check that our old index 1 was shifted to index 2 + assertEquals(29, list.get(2)); + // add index 3 at end of list, check size incremented and value was added + list.add(3, 67); + assertEquals(4, list.size()); + assertEquals(67, list.get(3)); + // add to index 0, check that everything got shifted over properly + list.add(0, 99); + assertEquals(5, list.size()); + assertEquals(99, list.get(0)); + assertEquals(4, list.get(1)); + assertEquals(12, list.get(2)); + assertEquals(29, list.get(3)); + assertEquals(67, list.get(4)); + } + + @Test + void removeFront() { + LinkedIntList list = new LinkedIntList(); // new list for testing + // add values for testing + list.addBack(12); + list.addBack(9); + list.addBack(44); + list.addBack(56); + list.addBack(20); + list.addBack(88); + // test size = 6 + assertEquals(6, list.size()); + // test get(0) = 12 + assertEquals(12, list.get(0)); + // remove front + list.removeFront(); + // test size = 5 + assertEquals(5, list.size()); + // test all values shifted over + assertEquals(9, list.get(0)); + assertEquals(44, list.get(1)); + assertEquals(56, list.get(2)); + assertEquals(20, list.get(3)); + assertEquals(88, list.get(4)); + // remove front + list.removeFront(); + // test size = 4 (decremented) + assertEquals(4, list.size()); + // test values shifted over + assertEquals(44, list.get(0)); + assertEquals(56, list.get(1)); + assertEquals(20, list.get(2)); + assertEquals(88, list.get(3)); + } + + @Test + void removeBack() { + LinkedIntList list = new LinkedIntList(); // new list for testing + // add 1 item + list.addBack(12); + // test size = 1 + assertEquals(1, list.size()); + // remove back item + list.removeBack(); + // test size = 0 + assertEquals(0, list.size()); + list.addBack(19); + list.addBack(44); + list.addBack(99); + list.addBack(10); + list.addBack(5); + assertEquals(5, list.size()); + assertEquals(5, list.get(list.size()-1)); + list.removeBack(); + assertEquals(4, list.size()); + assertEquals(10, list.get(list.size()-1)); + list.removeBack(); + assertEquals(3, list.size()); + assertEquals(99, list.get(list.size()-1)); + list.removeBack(); + assertEquals(2, list.size()); + assertEquals(44, list.get(list.size()-1)); + list.removeBack(); + assertEquals(1, list.size()); + assertEquals(19, list.get(list.size()-1)); + list.removeBack(); + assertEquals(0, list.size()); + } + + @Test + void remove() { + LinkedIntList list = new LinkedIntList(); // new list for testing + // add 1 item + list.addBack(12); + // test size = 1 + assertEquals(1, list.size()); + // remove our only item + list.remove(0); + // test size = 0 + assertEquals(0, list.size()); + // add 4 items + list.addBack(87); + list.addBack(41); + list.addBack(22); + list.addBack(76); + // test size = 0 + assertEquals(4, list.size()); + assertEquals(41, list.get(1)); + // remove index 1 + list.remove(1); + // test size was decremented + assertEquals(3, list.size()); + // test all values were shifted over + assertEquals(87, list.get(0)); + assertEquals(22, list.get(1)); + assertEquals(76, list.get(2)); + + } + + @Test + void get() { + LinkedIntList list = new LinkedIntList(); // new list for testing + // add values to test get() + list.addBack(77); + list.addBack(21); + list.addBack(33); + list.addBack(10); + list.addBack(8); + list.addBack(68); + list.addBack(93); + // check that get() returns the correct values + assertEquals(33, list.get(2)); + assertEquals(8, list.get(4)); + assertEquals(21, list.get(1)); + assertEquals(77, list.get(0)); + assertEquals(68, list.get(5)); + } + + @Test + void contains() { + LinkedIntList list = new LinkedIntList(); // new list for testing + // add values to test contains() + list.addBack(6); + list.addBack(13); + list.addBack(40); + list.addBack(78); + list.addBack(120); + list.addBack(36); + // check for values within the list using contains() + assertEquals(true, list.contains(6)); + assertEquals(false, list.contains(7)); + assertEquals(true, list.contains(13)); + assertEquals(true, list.contains(36)); + assertEquals(true, list.contains(120)); + assertEquals(true, list.contains(40)); + assertEquals(false, list.contains(600)); + assertEquals(false, list.contains(18928475)); + assertEquals(false, list.contains(1)); + } + + @Test + void indexOf() { + LinkedIntList list = new LinkedIntList(); // new list for testing + // add values + list.addBack(1); + list.addBack(100); + list.addBack(24); + list.addBack(81); + list.addBack(33); + // test for values that exist and don't exist + assertEquals(0, list.indexOf(1)); + assertEquals(-1, list.indexOf(19)); + assertEquals(-1, list.indexOf(44)); + assertEquals(3, list.indexOf(81)); + assertEquals(4, list.indexOf(33)); + assertEquals(-1, list.indexOf(99)); + assertEquals(1, list.indexOf(100)); + assertEquals(2, list.indexOf(24)); + } + + @Test + void isEmpty() { + LinkedIntList list = new LinkedIntList(); // new list for testing + // test empty list is empty + assertEquals(true, list.isEmpty()); + list.addFront(12); + // test list with 1 item is not empty + assertEquals(false, list.isEmpty()); + list.removeFront(); + // test now empty list is empty + assertEquals(true, list.isEmpty()); + list.addFront(12); + list.addFront(12); + list.addFront(12); + list.addFront(12); + // test list with 4 items is not empty + assertEquals(false, list.isEmpty()); + } + + @Test + void size() { + LinkedIntList list = new LinkedIntList(); // new list for testing + // test size = 0 + assertEquals(0, list.size()); + list.addFront(12); + // test size = 1 + assertEquals(1, list.size()); + list.addFront(12); + list.addFront(12); + list.addFront(12); + list.addFront(12); + list.addFront(12); + // test size = 6 + assertEquals(6, list.size()); + list.removeFront(); + list.removeFront(); + list.removeFront(); + list.removeFront(); + // test size = 2 + assertEquals(2, list.size()); + } + + @Test + void clear() { + LinkedIntList list = new LinkedIntList(); // new list for testing + // add 1 item, test clear + list.addFront(12); + assertEquals(1, list.size()); + list.clear(); + assertEquals(0, list.size()); + // add 3 items, test clear + list.addFront(12); + list.addFront(12); + list.addFront(12); + assertEquals(3, list.size()); + list.clear(); + assertEquals(0, list.size()); + } +} \ No newline at end of file