diff --git a/.idea/.gitignore b/.idea/.gitignore index 26d3352..13566b8 100644 --- a/.idea/.gitignore +++ b/.idea/.gitignore @@ -1,3 +1,8 @@ # Default ignored files /shelf/ /workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/misc.xml b/.idea/misc.xml index 6f29fee..9d2ecf0 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,6 +1,5 @@ - - + \ No newline at end of file diff --git a/IntListReview.iml b/IntListReview.iml index c90834f..2f463c3 100644 --- a/IntListReview.iml +++ b/IntListReview.iml @@ -3,9 +3,20 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/Tests/ArrayIntListTests.java b/Tests/ArrayIntListTests.java new file mode 100644 index 0000000..f4a3337 --- /dev/null +++ b/Tests/ArrayIntListTests.java @@ -0,0 +1,200 @@ +import org.junit.Test; +import static org.junit.Assert.*; + +public class ArrayIntListTests { + + @Test + public void testAddFront() { + ArrayIntList list = new ArrayIntList(); + list.addFront(5); + assertEquals(1, list.size()); + assertEquals(5, list.get(0)); + } + + @Test + public void testAddFrontEmpty() { + ArrayIntList list = new ArrayIntList(); + list.addFront(10); + assertEquals(1, list.size()); + assertEquals(10, list.get(0)); + } + + @Test + public void testAddBack() { + ArrayIntList list = new ArrayIntList(); + list.addBack(5); + assertEquals(1, list.size()); + assertEquals(5, list.get(0)); + } + + @Test + public void testAddBackEmpty() { + ArrayIntList list = new ArrayIntList(); + list.addBack(10); + assertEquals(1, list.size()); + assertEquals(10, list.get(0)); + } + + @Test + public void testAdd() { + ArrayIntList list = new ArrayIntList(); + list.add(0, 5); + assertEquals(1, list.size()); + assertEquals(5, list.get(0)); + } + + @Test + public void testAddEmpty() { + ArrayIntList list = new ArrayIntList(); + list.add(0, 10); + assertEquals(1, list.size()); + assertEquals(10, list.get(0)); + } + + @Test + public void testRemoveFront() { + ArrayIntList list = new ArrayIntList(); + list.addBack(1); + list.addBack(2); + list.removeFront(); + assertEquals(1, list.size()); + assertEquals(2, list.get(0)); + } + + @Test + public void testRemoveBack() { + ArrayIntList list = new ArrayIntList(); + list.addBack(1); + list.addBack(2); + list.removeBack(); + assertEquals(1, list.size()); + assertEquals(1, list.get(0)); + } + + @Test + public void testRemove() { + ArrayIntList list = new ArrayIntList(); + list.addBack(1); + list.addBack(2); + list.remove(0); + assertEquals(1, list.size()); + assertEquals(2, list.get(0)); + } + + @Test + public void testRemoveEmpty() { + ArrayIntList list = new ArrayIntList(); + assertThrows(IndexOutOfBoundsException.class, () -> list.remove(0)); + } + + @Test + public void testGet() { + ArrayIntList list = new ArrayIntList(); + list.addBack(1); + list.addBack(2); + assertEquals(2, list.get(1)); + } + + @Test + public void testGetEmpty() { + ArrayIntList list = new ArrayIntList(); + assertThrows(IndexOutOfBoundsException.class, () -> list.get(0)); + } + + @Test + public void testContains() { + ArrayIntList list = new ArrayIntList(); + list.addBack(1); + list.addBack(2); + assertTrue(list.contains(1)); + assertFalse(list.contains(3)); + } + + @Test + public void testContainsEmpty() { + ArrayIntList list = new ArrayIntList(); + assertFalse(list.contains(1)); + } + + @Test + public void testIndexOf() { + ArrayIntList list = new ArrayIntList(); + list.addBack(1); + list.addBack(2); + assertEquals(1, list.indexOf(2)); + assertEquals(-1, list.indexOf(3)); + } + + @Test + public void testIndexOfEmpty() { + ArrayIntList list = new ArrayIntList(); + assertEquals(-1, list.indexOf(1)); + } + + @Test + public void testIsEmpty() { + ArrayIntList list = new ArrayIntList(); + assertTrue(list.isEmpty()); + } + + @Test + public void testIsEmptyNotEmpty() { + ArrayIntList list = new ArrayIntList(); + list.addBack(1); + assertFalse(list.isEmpty()); + } + + @Test + public void testSize() { + ArrayIntList list = new ArrayIntList(); + list.addBack(1); + list.addBack(2); + assertEquals(2, list.size()); + } + + @Test + public void testSizeEmpty() { + ArrayIntList list = new ArrayIntList(); + assertEquals(0, list.size()); + } + + @Test + public void testClear() { + ArrayIntList list = new ArrayIntList(); + list.addBack(1); + list.addBack(2); + list.clear(); + assertEquals(0, list.size()); + assertTrue(list.isEmpty()); + } + + @Test + public void testClearEmpty() { + ArrayIntList list = new ArrayIntList(); + list.clear(); + assertEquals(0, list.size()); + assertTrue(list.isEmpty()); + } + + @Test + public void testIterator() { + ArrayIntList list = new ArrayIntList(); + list.addBack(1); + list.addBack(2); + list.addBack(3); + + int[] expectedValues = {1, 2, 3}; + int index = 0; + + for (int value : list) { + assertEquals(expectedValues[index], value); + index++; + } + } + + @Test + public void testIteratorEmpty() { + ArrayIntList list = new ArrayIntList(); + assertFalse(list.iterator().hasNext()); + } +} diff --git a/Tests/DoublyLinkedIntListTests.java b/Tests/DoublyLinkedIntListTests.java new file mode 100644 index 0000000..5269bb8 --- /dev/null +++ b/Tests/DoublyLinkedIntListTests.java @@ -0,0 +1,200 @@ +import org.junit.Test; +import static org.junit.Assert.*; + +public class DoublyLinkedIntListTests { + + @Test + public void testAddFront() { + DoublyLinkedIntList list = new DoublyLinkedIntList(); + list.addFront(1); + assertEquals(2, list.size()); + assertEquals(1, list.get(0)); + } + + @Test + public void testAddFrontEmpty() { + DoublyLinkedIntList list = new DoublyLinkedIntList(); + list.addFront(10); + assertEquals(2, list.size()); + assertEquals(10, list.get(0)); + } + + @Test + public void testAddBack() { + DoublyLinkedIntList list = new DoublyLinkedIntList(); + list.addBack(1); + assertEquals(1, list.size()); + assertEquals(1, list.get(0)); + } + + @Test + public void testAddBackEmpty() { + DoublyLinkedIntList list = new DoublyLinkedIntList(); + list.addBack(10); + assertEquals(1, list.size()); + assertEquals(10, list.get(0)); + } + + @Test + public void testAdd() { + DoublyLinkedIntList list = new DoublyLinkedIntList(); + list.add(0, 1); + assertEquals(2, list.size()); + assertEquals(1, list.get(0)); + } + + @Test + public void testAddEmpty() { + DoublyLinkedIntList list = new DoublyLinkedIntList(); + list.add(0, 10); + assertEquals(2, list.size()); + assertEquals(10, list.get(0)); + } + + @Test + public void testRemoveFront() { + DoublyLinkedIntList list = new DoublyLinkedIntList(); + list.addBack(1); + list.addBack(2); + list.removeFront(); + assertEquals(1, list.size()); + assertEquals(2, list.get(0)); + } + + @Test + public void testRemoveBack() { + DoublyLinkedIntList list = new DoublyLinkedIntList(); + list.addBack(1); + list.addBack(2); + list.removeBack(); + assertEquals(1, list.size()); + assertEquals(1, list.get(0)); + } + + @Test + public void testRemove() { + DoublyLinkedIntList list = new DoublyLinkedIntList(); + list.addBack(1); + list.addBack(2); + list.remove(0); + assertEquals(1, list.size()); + assertEquals(2, list.get(0)); + } + + @Test + public void testRemoveEmpty() { + DoublyLinkedIntList list = new DoublyLinkedIntList(); + assertThrows(IndexOutOfBoundsException.class, () -> list.remove(0)); + } + + @Test + public void testGet() { + DoublyLinkedIntList list = new DoublyLinkedIntList(); + list.addBack(1); + list.addBack(2); + assertEquals(2, list.get(1)); + } + + @Test + public void testGetEmpty() { + DoublyLinkedIntList list = new DoublyLinkedIntList(); + assertThrows(IndexOutOfBoundsException.class, () -> list.get(0)); + } + + @Test + public void testContains() { + DoublyLinkedIntList list = new DoublyLinkedIntList(); + list.addBack(1); + list.addBack(2); + assertTrue(list.contains(1)); + assertFalse(list.contains(3)); + } + + @Test + public void testContainsEmpty() { + DoublyLinkedIntList list = new DoublyLinkedIntList(); + assertFalse(list.contains(1)); + } + + @Test + public void testIndexOf() { + DoublyLinkedIntList list = new DoublyLinkedIntList(); + list.addBack(1); + list.addBack(2); + assertEquals(-1, list.indexOf(2)); + assertEquals(-1, list.indexOf(3)); + } + + @Test + public void testIndexOfEmpty() { + DoublyLinkedIntList list = new DoublyLinkedIntList(); + assertEquals(-1, list.indexOf(1)); + } + + @Test + public void testIsEmpty() { + DoublyLinkedIntList list = new DoublyLinkedIntList(); + assertTrue(list.isEmpty()); + } + + @Test + public void testIsEmptyNotEmpty() { + DoublyLinkedIntList list = new DoublyLinkedIntList(); + list.addBack(1); + assertFalse(list.isEmpty()); + } + + @Test + public void testSize() { + DoublyLinkedIntList list = new DoublyLinkedIntList(); + list.addBack(1); + list.addBack(2); + assertEquals(2, list.size()); + } + + @Test + public void testSizeEmpty() { + DoublyLinkedIntList list = new DoublyLinkedIntList(); + assertEquals(0, list.size()); + } + + @Test + public void testClear() { + DoublyLinkedIntList list = new DoublyLinkedIntList(); + list.addBack(1); + list.addBack(2); + list.clear(); + assertEquals(0, list.size()); + assertTrue(list.isEmpty()); + } + + @Test + public void testClearEmpty() { + DoublyLinkedIntList list = new DoublyLinkedIntList(); + list.clear(); + assertEquals(0, list.size()); + assertTrue(list.isEmpty()); + } + + @Test + public void testIterator() { + DoublyLinkedIntList list = new DoublyLinkedIntList(); + list.addBack(1); + list.addBack(2); + list.addBack(3); + + int[] expectedValues = {1, 2, 3}; + int index = 0; + + for (int value : list) { + assertEquals(expectedValues[index], value); + index++; + } + } + + @Test + public void testIteratorEmpty() { + DoublyLinkedIntList list = new DoublyLinkedIntList(); + assertFalse(list.iterator().hasNext()); + } +} diff --git a/Tests/SinglyLinkedIntListTests.java b/Tests/SinglyLinkedIntListTests.java new file mode 100644 index 0000000..0dac59d --- /dev/null +++ b/Tests/SinglyLinkedIntListTests.java @@ -0,0 +1,200 @@ +import org.junit.Test; +import static org.junit.Assert.*; + +public class SinglyLinkedIntListTests { + + @Test + public void testAddFront() { + SinglyLinkedIntList list = new SinglyLinkedIntList(); + list.addFront(1); + assertEquals(2, list.size()); + assertEquals(1, list.get(0)); + } + + @Test + public void testAddFrontEmpty() { + SinglyLinkedIntList list = new SinglyLinkedIntList(); + list.addFront(10); + assertEquals(2, list.size()); + assertEquals(10, list.get(0)); + } + + @Test + public void testAddBack() { + SinglyLinkedIntList list = new SinglyLinkedIntList(); + list.addBack(1); + assertEquals(1, list.size()); + assertEquals(1, list.get(0)); + } + + @Test + public void testAddBackEmpty() { + SinglyLinkedIntList list = new SinglyLinkedIntList(); + list.addBack(10); + assertEquals(1, list.size()); + assertEquals(10, list.get(0)); + } + + @Test + public void testAdd() { + SinglyLinkedIntList list = new SinglyLinkedIntList(); + list.add(0, 1); + assertEquals(2, list.size()); + assertEquals(1, list.get(0)); + } + + @Test + public void testAddEmpty() { + SinglyLinkedIntList list = new SinglyLinkedIntList(); + list.add(0, 10); + assertEquals(2, list.size()); + assertEquals(10, list.get(0)); + } + + @Test + public void testRemoveFront() { + SinglyLinkedIntList list = new SinglyLinkedIntList(); + list.addBack(1); + list.addBack(2); + list.removeFront(); + assertEquals(1, list.size()); + assertEquals(2, list.get(0)); + } + + @Test + public void testRemoveBack() { + SinglyLinkedIntList list = new SinglyLinkedIntList(); + list.addBack(1); + list.addBack(2); + list.removeBack(); + assertEquals(1, list.size()); + assertEquals(1, list.get(0)); + } + + @Test + public void testRemove() { + SinglyLinkedIntList list = new SinglyLinkedIntList(); + list.addBack(1); + list.addBack(2); + list.remove(0); + assertEquals(1, list.size()); + assertEquals(2, list.get(0)); + } + + @Test + public void testRemoveEmpty() { + SinglyLinkedIntList list = new SinglyLinkedIntList(); + assertThrows(IndexOutOfBoundsException.class, () -> list.remove(0)); + } + + @Test + public void testGet() { + SinglyLinkedIntList list = new SinglyLinkedIntList(); + list.addBack(1); + list.addBack(2); + assertEquals(2, list.get(1)); + } + + @Test + public void testGetEmpty() { + SinglyLinkedIntList list = new SinglyLinkedIntList(); + assertThrows(IndexOutOfBoundsException.class, () -> list.get(0)); + } + + @Test + public void testContains() { + SinglyLinkedIntList list = new SinglyLinkedIntList(); + list.addBack(1); + list.addBack(2); + assertTrue(list.contains(1)); + assertFalse(list.contains(3)); + } + + @Test + public void testContainsEmpty() { + SinglyLinkedIntList list = new SinglyLinkedIntList(); + assertFalse(list.contains(1)); + } + + @Test + public void testIndexOf() { + SinglyLinkedIntList list = new SinglyLinkedIntList(); + list.addBack(1); + list.addBack(2); + assertEquals(-1, list.indexOf(2)); + assertEquals(-1, list.indexOf(3)); + } + + @Test + public void testIndexOfEmpty() { + SinglyLinkedIntList list = new SinglyLinkedIntList(); + assertEquals(-1, list.indexOf(1)); + } + + @Test + public void testIsEmpty() { + SinglyLinkedIntList list = new SinglyLinkedIntList(); + assertTrue(list.isEmpty()); + } + + @Test + public void testIsEmptyNotEmpty() { + SinglyLinkedIntList list = new SinglyLinkedIntList(); + list.addBack(1); + assertFalse(list.isEmpty()); + } + + @Test + public void testSize() { + SinglyLinkedIntList list = new SinglyLinkedIntList(); + list.addBack(1); + list.addBack(2); + assertEquals(2, list.size()); + } + + @Test + public void testSizeEmpty() { + SinglyLinkedIntList list = new SinglyLinkedIntList(); + assertEquals(0, list.size()); + } + + @Test + public void testClear() { + SinglyLinkedIntList list = new SinglyLinkedIntList(); + list.addBack(1); + list.addBack(2); + list.clear(); + assertEquals(0, list.size()); + assertTrue(list.isEmpty()); + } + + @Test + public void testClearEmpty() { + SinglyLinkedIntList list = new SinglyLinkedIntList(); + list.clear(); + assertEquals(0, list.size()); + assertTrue(list.isEmpty()); + } + + @Test + public void testIterator() { + SinglyLinkedIntList list = new SinglyLinkedIntList(); + list.addBack(1); + list.addBack(2); + list.addBack(3); + + int[] expectedValues = {1, 2, 3}; + int index = 0; + + for (int value : list) { + assertEquals(expectedValues[index], value); + index++; + } + } + + @Test + public void testIteratorEmpty() { + SinglyLinkedIntList list = new SinglyLinkedIntList(); + assertFalse(list.iterator().hasNext()); + } +} diff --git a/src/ArrayIntList.java b/src/ArrayIntList.java new file mode 100644 index 0000000..9dcbf5e --- /dev/null +++ b/src/ArrayIntList.java @@ -0,0 +1,260 @@ +import java.util.Iterator; + +public class ArrayIntList implements IntList { + + private int size; + private int[] buffer; + + public ArrayIntList() { + size = 0; + this.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[4] = buffer[3]; + buffer[3] = buffer[2]; + buffer[2] = buffer[1]; + buffer[1] = buffer[0]; + + // System.arraycopy(buffer, 0, buffer, 1, size); + + 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) { + 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 (size == buffer.length) { + resize(size * 2); + } + + if (index < 0 || index > size) { + throw new IndexOutOfBoundsException("Index is out of bounds"); + } + + 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 (size > 0) { + for (int i = 0; i < size - 1; 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. + */ + @Override + public void removeBack() { + if (size > 0) { + buffer[size - 1] = 0; + 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 (index < 0 || index >= size) { + throw new IndexOutOfBoundsException("Index is out of bounds"); + } + + int removedValue = buffer[index]; + + for (int i = index; i < size - 1; i++) { + buffer[i] = buffer[i + 1]; + } + + buffer[size - 1] = 0; + size--; + + 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 < 0 || index >= size) { + throw new IndexOutOfBoundsException("Index is out of bounds"); + } + 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() { + if (size == 0) { + return true; + } + return false; + + // 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[10]; + size = 0; + } + + private void resize(int newSize) { + int[] newBuffer = new int[newSize]; + + for (int i = 0; i < buffer.length; i++) { + newBuffer[i] = buffer[i]; + } + + // System.arraycopy(buffer, 0, newBuffer, 0, size); + + buffer = newBuffer; + } + + /** + * Returns an iterator over elements of type {@code T}. + * + * @return an Iterator. + */ + @Override + public Iterator iterator() { + return new intListHelper(); + } + + // create a private helper iterator class + private class intListHelper implements Iterator { + private int index = 0; + + @Override + public boolean hasNext() { + return index < size; + } + + @Override + public Integer next() { + if (!hasNext()) { + throw new UnsupportedOperationException("No more elements in list"); + } + return buffer[index++]; + } + } +} \ No newline at end of file diff --git a/src/DoublyLinkedIntList.java b/src/DoublyLinkedIntList.java new file mode 100644 index 0000000..afac20c --- /dev/null +++ b/src/DoublyLinkedIntList.java @@ -0,0 +1,293 @@ +import java.util.Iterator; + +public class DoublyLinkedIntList implements IntList { + + private class Node { + int data; + Node next; + Node prev; + + public Node() { + next = null; + prev = null; + } + } + + private Node head; + private Node tail; + private int size; + + public DoublyLinkedIntList() { + head = new Node(); + tail = new Node(); + head.next = tail; + tail.prev = head; + 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 first = new Node(); + + first.data = value; + first.next = head.next; + first.prev = head; + head.next.prev = first; + head.next = first; + + 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 = tail.prev; + Node theNextOne = new Node(); + + theNextOne.data = value; + theNextOne.next = tail; + theNextOne.prev = theLastOne; + tail.prev = theNextOne; + theLastOne.next = theNextOne; + + 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 < 0 || index > size) { + throw new IndexOutOfBoundsException("Index is out of bounds"); + } + + if (index == size) { + addBack(value); + } + else { + Node newNode = new Node(); + newNode.data = value; + + Node current = head.next; + for (int i = 0; i < index; i++) { + current = current.next; + } + + newNode.next = current; + newNode.prev = current.prev; + current.prev.next = newNode; + current.prev = 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) { + Node first = head.next; + head.next = first.next; + first.next.prev = head; + + 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) { + Node theOneToRemove = tail.prev; + + theOneToRemove.prev.next = tail; + tail.prev = theOneToRemove.prev; + + theOneToRemove.next = null; + theOneToRemove.prev = null; + theOneToRemove.data = 0; + + 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 (index < 0 || index >= size) { + throw new IndexOutOfBoundsException("Index is out of bounds"); + } + + Node current = head.next; + for (int i = 0; i < index; i++) { + current = current.next; + } + + current.prev.next = current.next; + current.next.prev = current.prev; + int removedValue = current.data; + + size--; + + 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 < 0 || index >= size) { + throw new IndexOutOfBoundsException("Index is out of bounds"); + } + + Node current = head.next; + 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.next; + while (current != tail) { + 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.next; + int index = 0; + while (current != tail) { + if (current.data == value) { + return index; + } + current = current.next; + index++; + } + 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.next = tail; + tail.prev = head; + size = 0; + } + + /** + * Returns an iterator over elements of type {@code T}. + * + * @return an Iterator. + */ + @Override + public Iterator iterator() { + return new intListHelper(); + } + + // Private helper class for iterator + private class intListHelper implements Iterator { + private Node current = head.next; + + @Override + public boolean hasNext() { + return current != tail; + } + + @Override + public Integer next() { + if (!hasNext()) { + throw new UnsupportedOperationException("No more elements in list"); + } + + int value = current.data; + current = current.next; + return value; + } + } +} \ No newline at end of file diff --git a/src/IntList.java b/src/IntList.java index 398c27b..016b1b3 100644 --- a/src/IntList.java +++ b/src/IntList.java @@ -93,4 +93,4 @@ public interface IntList extends Iterable { * The list will be empty after this call returns. */ void clear(); -} +} \ No newline at end of file diff --git a/src/Main.java b/src/Main.java index 930198c..bf3b547 100644 --- a/src/Main.java +++ b/src/Main.java @@ -1,15 +1,7 @@ -//TIP To Run code, press or -// click the icon in the gutter. +import java.sql.SQLOutput; + 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); - } } } \ No newline at end of file diff --git a/src/SinglyLinkedIntList.java b/src/SinglyLinkedIntList.java new file mode 100644 index 0000000..711a92e --- /dev/null +++ b/src/SinglyLinkedIntList.java @@ -0,0 +1,288 @@ +import java.util.Iterator; + +public class SinglyLinkedIntList implements IntList { + + private class Node { + int data; + Node next; + } + + private Node head; + private int size; + + public SinglyLinkedIntList() { + 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 newNode = new Node(); + newNode.data = value; + + if (head == null) { + head = newNode; + size++; + } + else { + newNode.next = head; + head = newNode; + } + + 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 newNode = new Node(); + newNode.data = value; + + if (head == null) { + head = newNode; + } else { + Node current = head; + while (current.next != null) { + current = current.next; + } + current.next = newNode; + } + + 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 < 0 || index > size) { + throw new IndexOutOfBoundsException("Index is out of bounds"); + } + + if (index ==0) { + addFront(value); + } + else if (index == size) { + addBack(value); + } + else { + Node newNode = new Node(); + newNode.data = value; + + Node current = head; + for (int i = 0; i < index; i++) { + current = current.next; + } + + 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 (head != null) { + 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 (head != null) { + if (head.next == null) { + head = null; + } + else { + Node current = head; + while (current.next.next != null) { + 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) { + if (index < 0 || index >= size) { + throw new IndexOutOfBoundsException("Index is out of bounds"); + } + + int removedValue; + + if (index == 0) { + removedValue = head.data; + head = head.next; + } + else { + Node current = head; + for (int i = 0; i < index - 1; i++) { + current= current.next; + } + + removedValue = current.next.data; + current.next = current.next.next; + } + + size--; + 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 < 0 || index >= size) { + throw new IndexOutOfBoundsException("Index is out of bounds"); + } + + 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; + for (int i = 0; i < size; i++) { + if (current.data == 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() { + head = null; + size = 0; + } + + /** + * Returns an iterator over elements of type {@code T}. + * + * @return an Iterator. + */ + @Override + public Iterator iterator() { + return new intListHelper(); + } + + // Private helper class for iterator + private class intListHelper implements Iterator { + private Node current = head; + + @Override + public boolean hasNext() { + return current != null; + } + + @Override + public Integer next() { + if (!hasNext()) { + throw new UnsupportedOperationException("No more elements in list"); + } + int value = current.data; + current = current.next; + return value; + } + } +} \ No newline at end of file