From 540c4a82d3d9827a729c513ce933ec73aba69598 Mon Sep 17 00:00:00 2001 From: kayleyyoung253 Date: Mon, 19 Feb 2024 12:43:51 -0800 Subject: [PATCH 01/18] Added ArrayList Java class to implement all the methods of the List interface. --- src/ArrayList.java | 144 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 144 insertions(+) create mode 100644 src/ArrayList.java diff --git a/src/ArrayList.java b/src/ArrayList.java new file mode 100644 index 0000000..26f62d3 --- /dev/null +++ b/src/ArrayList.java @@ -0,0 +1,144 @@ +import java.util.Iterator; + +/** + * + * implement all of the methods in the List interface, and implement the interator() + * method from the iterable interface + */ +public class ArrayList implements List { + /** + * Add item to the front. + * + * @param item the item to be added + */ + @Override + public void addFront(E item) { + + } + + /** + * Add item to the back. + * + * @param item the item to be added + */ + @Override + public void addBack(E item) { + + } + + /** + * Add an item at specified index (position). + * + * @param i the index where the item should be added + * @param item the item to be added + */ + @Override + public void add(int i, E item) { + + } + + /** + * Get the item at a specified index. + * + * @param i the index where the item should be retrieved + * @return the item located at that index + */ + @Override + public E get(int i) { + return null; + } + + /** + * Set (save) an item at a specified index. Previous + * item at that index is overwritten. + * + * @param i the index where the item should be saved + * @param item the item to be saved + */ + @Override + public void set(int i, E item) { + + } + + /** + * Remove item at the front of the list. + * + * @return the item that was removed + */ + @Override + public E removeFront() { + return null; + } + + /** + * Remove item at the back of the list + * + * @return the item that was removed + */ + @Override + public E removeBack() { + return null; + } + + /** + * Remove item from the list + * + * @param item the item to be removed + */ + @Override + public void remove(E item) { + + } + + /** + * Remove item at a specified index. + * + * @param i the index where the item should be removed + * @return the item that was removed + */ + @Override + public E remove(int i) { + return null; + } + + /** + * Checks if an item is in the list. + * + * @param item the item to search for + * @return true if the item is in the list, false otherwise + */ + @Override + public boolean contains(E item) { + return false; + } + + /** + * Checks if the list is empty. + * + * @return true if the list is empty, false otherwise + */ + @Override + public boolean isEmpty() { + return false; + } + + /** + * Provides a count of the number of items in the list. + * + * @return number of items in the list + */ + @Override + public int size() { + return 0; + } + + /** + * Returns an iterator over elements of type {@code T}. + * + * @return an Iterator. + */ + @Override + public Iterator iterator() { + return null; + } +} From 381dca9354c73be3d71ef4c7af4fd2948c5f5871 Mon Sep 17 00:00:00 2001 From: kayleyyoung253 Date: Mon, 19 Feb 2024 22:22:08 -0800 Subject: [PATCH 02/18] created test class for ArrayList.java --- test/ArrayListTest.java | 185 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 185 insertions(+) create mode 100644 test/ArrayListTest.java diff --git a/test/ArrayListTest.java b/test/ArrayListTest.java new file mode 100644 index 0000000..f874a36 --- /dev/null +++ b/test/ArrayListTest.java @@ -0,0 +1,185 @@ +import static org.junit.jupiter.api.Assertions.*; + +class ArrayListTest { + + @org.junit.jupiter.api.Test + void addFront() { + ArrayList list = new ArrayList(); + list.addFront(0); + assertEquals(0,list.get(0)); + list.add(0,1); + list.addFront(-1); + assertEquals(-1,list.get(0)); + list.addFront(1); + list.addFront(2); + list.addFront(3); + list.addFront(4); + list.addFront(5); + list.addFront(6); + list.addFront(7); + list.addFront(8); + list.addFront(9); + assertEquals(9,list.get(0)); + } + + @org.junit.jupiter.api.Test + void addBack() { + ArrayList list = new ArrayList(); + list.add(0,1); + list.addFront(0); + list.addFront(-1); + list.addBack(2); + assertEquals(2,list.get(list.size()-1)); + list.addBack(3); + list.addBack(4); + list.addBack(5); + list.addBack(6); + list.addBack(7); + list.addBack(8); + list.addBack(9); + list.addBack(10); + assertEquals(10,list.get(list.size()-1)); + } + + @org.junit.jupiter.api.Test + void add() { + ArrayList list = new ArrayList(); + list.add(0,0); + list.add(1,1); + list.add(2,2); + list.add(3,3); + list.add(4,4); + list.add(5,5); + list.add(6,6); + list.add(7,7); + list.add(8,8); + list.add(9,9); + list.add(10,10); + list.add(11,11);//resizes + + // list.add(-1,0); //this should throw IndexOutOfBoundsException with note on "Index cannot be negative") + assertEquals(0,list.get(0)); + assertEquals(10,list.get(10)); + assertEquals(11,list.get(11)); + } + + @org.junit.jupiter.api.Test + void get() { + ArrayList list = new ArrayList(); + //list.get(0); //array is empty throws IndexOutOfBoundsException: Index is higher than size + list.add(0,0); + assertEquals(0, list.get(0)); + list.add(1,1); + list.add(2,2); + list.add(3,3); + list.add(4,4); + list.add(5,5); + list.add(6,6); + list.add(7,7); + list.add(8,8); + list.add(9,9); + list.add(10,10); + list.add(11,11); + assertEquals(1,list.get(1)); + assertEquals(11,list.get(11)); + //list.get(-1); //throws IndexOutOfBoundsException: Index cannot be negative + } + + @org.junit.jupiter.api.Test + void set() { + ArrayList list = new ArrayList(); + list.add(0,0); + assertEquals(0, list.get(0)); + list.set(0,1); + assertEquals(1, list.get(0)); + list.add(1,1); + list.add(2,2); + list.add(3,3); + list.add(4,4); + list.add(5,5); + list.add(6,6); + list.add(7,7); + list.add(8,8); + list.add(9,9); + list.add(10,10); + list.add(11,11); + list.set(11,100); + assertEquals(100, list.get(11)); + } + + @org.junit.jupiter.api.Test + void removeFront() { + ArrayList list = new ArrayList(); + // list.removeFront(); //array is empty, should throw IndexOutOfBoundsException("Array is empty, nothing to remove"); + list.add(0,0); + list.removeFront(); + //test the removal of front from array with only 1 value, deletion makes array empty + assertEquals(0,list.size()); + list.add(0,0); + list.add(1,1); + list.add(2,2); + list.removeFront(); + assertEquals(2,list.get(list.size()-1)); + assertEquals(1,list.get(0)); + list.add(2,3); + list.add(3,4); + list.add(4,5); + list.removeFront(); + assertEquals(2,list.get(0)); + list.add(4,6); + list.add(5,7); + list.add(6,8); + list.add(7,9); + list.add(8,10); + list.add(9,11); + list.removeFront(); + assertEquals(3,list.get(0)); + } + + @org.junit.jupiter.api.Test + void removeBack() { + ArrayList list = new ArrayList(); + //list.removeBack(); //array is empty, should throw IndexOutOfBoundsException("Array is empty, nothing to remove"); + list.add(0,0); + list.removeBack();// remove only value in array, should have a size of 0 now. + assertEquals(0,list.size()); + list.add(0,1); + list.add(1,2); + list.add(2,3); + list.removeBack(); + assertEquals(2, list.get(list.size()-1)); + assertEquals(2, list.removeBack()); + } + + @org.junit.jupiter.api.Test + void remove() { + } + + @org.junit.jupiter.api.Test + void testRemove() { + } + + @org.junit.jupiter.api.Test + void contains() { + } + + @org.junit.jupiter.api.Test + void isEmpty() { + } + + @org.junit.jupiter.api.Test + void size() { + ArrayList list = new ArrayList(); + assertEquals(0, list.size()); + list.add(0,10); + assertEquals(1,list.size()); + list.add(2,10); + assertEquals(2,list.size()); + //list.removeFront(); + //assertEquals(1,list.size()); + } + + @org.junit.jupiter.api.Test + void iterator() { + } +} \ No newline at end of file From e1d01b9fb3821028d73aadf78225a42de4ceeacc Mon Sep 17 00:00:00 2001 From: kayleyyoung253 Date: Mon, 19 Feb 2024 22:22:59 -0800 Subject: [PATCH 03/18] completed addFront, addBack, add, resize, get, and set --- src/ArrayList.java | 174 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 166 insertions(+), 8 deletions(-) diff --git a/src/ArrayList.java b/src/ArrayList.java index 26f62d3..2878e08 100644 --- a/src/ArrayList.java +++ b/src/ArrayList.java @@ -4,80 +4,202 @@ * * implement all of the methods in the List interface, and implement the interator() * method from the iterable interface + * @author Kayley Young */ public class ArrayList implements List { + private int size; + private E[] buffer; + + /** + * add constructor + */ + public ArrayList(){ + //initialize my fields + size = 0; + //You can create a new array of primitive types like ints with syntax + // like buffer = new int[10]. In class, we did an example (in SymbolTable) + // buffer = (ItemType) new Object[10] to create an array of generic objects. + buffer = (E[]) new Object[10]; + } + /** * Add item to the front. + * This method runs in O(n) because the + * loop that shifts elements in the buffer + * has to iterate through n elements where n is the size of the buffer. + * the complexity class is linear. * * @param item the item to be added */ @Override public void addFront(E item) { + if (buffer.length == size){ + resize(size * 2); + } + + for (int i = size; i > 0 ; i--) { + buffer[i] = buffer[i-1]; + } + buffer[0] = item; + size++; } /** * Add item to the back. * + * O(1) for adding an item to the buffer. + * This is because the code simply adds the item variable + * to the buffer array and increments the size variable, + * the complexity class is constant. + * * @param item the item to be added */ @Override public void addBack(E item) { - + if (size == buffer.length){ + resize(size + 2); + } + buffer[size] = item; + size++; } /** * Add an item at specified index (position). * + * This method runs in O(n) because the loop that shifts elements + * in the buffer has to iterate through n elements where n is the size of the buffer. + * the complexity class is linear. + * * @param i the index where the item should be added * @param item the item to be added */ @Override public void add(int i, E item) { + if(i < 0){ + throw new IndexOutOfBoundsException("Index cannot be negative"); + } + if (size == buffer.length){ + resize(size + 2); + } + + for (int j = size; j > i; j--) { + buffer[j] = buffer[j-1]; + } + buffer[i] = item; + size++; + } + public void resize(int newSize){ + + //create new space, separate from the old space (buffer) + E[] newBuffer = (E[]) new Object[newSize]; + //copy everything over from buffer into newBuffer + for (int i = 0; i < buffer.length; i++) { + newBuffer[i] = buffer[i]; + } + // + buffer = newBuffer; + + // the old space is no longer "pointed to" and will eventually + // be cleaned up by the garbage collector } /** * Get the item at a specified index. * + *This method runs in O(1) because it only involves simple comparisons + * and returning a value from an array, regardless of the size of the array. + * the complexity class is constant. + * * @param i the index where the item should be retrieved * @return the item located at that index */ @Override public E get(int i) { - return null; + if(i < 0){ + throw new IndexOutOfBoundsException("Index cannot be negative"); + } + else if (i >= size){ + throw new IndexOutOfBoundsException("Index is higher than size"); + } + + return buffer[i]; } /** * Set (save) an item at a specified index. Previous * item at that index is overwritten. * + * This method runs in O(1) because it only has to checks + * the index of buffer and places 1 item inside it + * the complexity class is constant. + * * @param i the index where the item should be saved * @param item the item to be saved */ @Override public void set(int i, E item) { + if(i < 0){ + throw new IndexOutOfBoundsException("Index cannot be negative"); + } + else if (i >= size){ + throw new IndexOutOfBoundsException("Index is higher than size"); + } + + buffer[i] = item; } /** * Remove item at the front of the list. * + * in the worst case scenario this method is O(n). + * when removing an element from the array, + * we need to shift all the elements to the left by one position. + * This requires iterating through + * the array and shifting each element. + * the complexity class is linear. + * * @return the item that was removed */ @Override public E removeFront() { - return null; + if(!isEmpty()) { + E copyOfRemovedValue = null; + for (int i = 0; i <= size - 2; i++) { + copyOfRemovedValue = buffer[i]; + buffer[i] = buffer[i + 1]; + } + + //zero out the far right since everything was shifted to the left + buffer[size -1] = null; + size--; + return copyOfRemovedValue; + }else{ + throw new IndexOutOfBoundsException("Array is empty, nothing to remove"); + } } /** * Remove item at the back of the list * + * This method runs in O(1) because it only has to checks + * the index of size-1 in the buffer and set it to null + * the complexity class is constant. + * * @return the item that was removed */ @Override public E removeBack() { - return null; + if (!isEmpty()){ + E copyOfRemovedValue = buffer[size-1]; + buffer[size-1] = null; + size--; + return copyOfRemovedValue; + }else{ + throw new IndexOutOfBoundsException("Array is empty, nothing to remove"); + } } /** @@ -93,43 +215,79 @@ public void remove(E item) { /** * Remove item at a specified index. * + * in the worst case scenario this method is O(n). + * when the element to be removed is at the beginning of the buffer, + * all elements after it need to be shifted to the left by one position. + * the complexity class is linear. + * * @param i the index where the item should be removed * @return the item that was removed */ @Override public E remove(int i) { - return null; + if(i < 0){ + throw new IndexOutOfBoundsException("Index cannot be negative"); + } + else if (i>= size){ + throw new IndexOutOfBoundsException("Index is higher than size"); + } + + //save a copy of the value to be removed so we can return it later + E copyOfRemovedValue = buffer[i]; + + //shift values to the left + for (int j = i; j <= size -1; j++){ + buffer[j] = buffer[j+1]; + } + + buffer[size - 1] = null; + // don't forget to decrement size + size--; + + return copyOfRemovedValue; } /** * Checks if an item is in the list. * + *This method runs in O(n) because it has a single for loop that + * iterates through the buffer array of size n. the complexity class is linear. + * * @param item the item to search for * @return true if the item is in the list, false otherwise */ @Override public boolean contains(E item) { + for (int i = 0; i < size; i++) { + if (buffer[i] == item){ + return true; + } + } return false; } /** * Checks if the list is empty. * + * This method runs in O(1) because it only has to check 1 variable + * and the complexity class is constant. + * * @return true if the list is empty, false otherwise */ @Override public boolean isEmpty() { - return false; + return size == 0; } /** - * Provides a count of the number of items in the list. + * Provides a count of the number of items in the list.This method runs in O(1) because it only has to check 1 variable + * and the complexity class is constant. * * @return number of items in the list */ @Override public int size() { - return 0; + return size; } /** From 53fa229590cfa19567b6053919055ec023393594 Mon Sep 17 00:00:00 2001 From: kayleyyoung253 Date: Mon, 19 Feb 2024 23:03:54 -0800 Subject: [PATCH 04/18] completed removeFront, removeBack, remove(item), remove(i), contains, isEmpty, and size --- src/ArrayList.java | 29 +++++++++++++++++++++++++++-- test/ArrayListTest.java | 29 +++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 2 deletions(-) diff --git a/src/ArrayList.java b/src/ArrayList.java index 2878e08..57a54a7 100644 --- a/src/ArrayList.java +++ b/src/ArrayList.java @@ -192,8 +192,9 @@ public E removeFront() { */ @Override public E removeBack() { + E copyOfRemovedValue = buffer[size-1]; + if (!isEmpty()){ - E copyOfRemovedValue = buffer[size-1]; buffer[size-1] = null; size--; return copyOfRemovedValue; @@ -205,11 +206,35 @@ public E removeBack() { /** * Remove item from the list * + * in the worst case scenario this method is O(n^2) + * there is a nested loop inside the outer loop. + * The outer loop runs for each element in the buffer, + * and the inner loop runs for each element after the current element. This + * results in a worst-case where everthing needs to be shifted to the left, + * this is a quadratic time complexity. + * * @param item the item to be removed */ @Override public void remove(E item) { + if (!isEmpty()){ + for (int i = 0; i < buffer.length; i++) { + + if (buffer[i] == item) { + buffer[i] = null; + + //shift values to the left + for (int j = i; j <= size; j++) { + buffer[i] = buffer[i + 1]; + } + size--; + } + } + + }else{ + throw new IndexOutOfBoundsException("Array is empty, nothing to remove"); + } } /** @@ -258,7 +283,7 @@ else if (i>= size){ */ @Override public boolean contains(E item) { - for (int i = 0; i < size; i++) { + for (int i = 0; i < buffer.length; i++) { if (buffer[i] == item){ return true; } diff --git a/test/ArrayListTest.java b/test/ArrayListTest.java index f874a36..dbb3211 100644 --- a/test/ArrayListTest.java +++ b/test/ArrayListTest.java @@ -153,14 +153,43 @@ void removeBack() { @org.junit.jupiter.api.Test void remove() { + ArrayList list = new ArrayList(); + list.add(0,1); + list.add(1,2); + list.add(2,3); + list.remove("2"); + assertFalse(list.contains("2")); } @org.junit.jupiter.api.Test void testRemove() { + ArrayList list = new ArrayList(); + list.add(0,1); + list.add(1,2); + list.add(2,3); + assertEquals(2, list.remove(1)); + list.add(1,2); + list.add(3,4); + assertEquals(4,list.remove(3)); + list.add(3,4); + list.add(4,5); + list.add(5,6); + list.add(6,7); + list.add(7,8); + list.remove(7); + assertEquals(7,list.get(list.size()-1)); + } @org.junit.jupiter.api.Test void contains() { + ArrayList list = new ArrayList(); + assertFalse(list.contains(1)); + assertFalse(list.contains(-1)); + list.add(1,1); + list.add(2,2); + assertTrue( list.contains(1)); + assertTrue(list.contains(2)); } @org.junit.jupiter.api.Test From 9fae37431f1c2123391077ca7206edd9de85ee54 Mon Sep 17 00:00:00 2001 From: kayleyyoung253 Date: Tue, 20 Feb 2024 00:13:44 -0800 Subject: [PATCH 05/18] completed all tests --- src/ArrayList.java | 43 +++++++++++++++++++++++++++++++++-- test/ArrayListTest.java | 50 +++++++++++++++++++++++++++++++++++++---- 2 files changed, 87 insertions(+), 6 deletions(-) diff --git a/src/ArrayList.java b/src/ArrayList.java index 57a54a7..687afc8 100644 --- a/src/ArrayList.java +++ b/src/ArrayList.java @@ -1,4 +1,5 @@ import java.util.Iterator; +import java.util.NoSuchElementException; /** * @@ -261,7 +262,7 @@ else if (i>= size){ E copyOfRemovedValue = buffer[i]; //shift values to the left - for (int j = i; j <= size -1; j++){ + for (int j = i; j < size - 1; j++){ buffer[j] = buffer[j+1]; } @@ -322,6 +323,44 @@ public int size() { */ @Override public Iterator iterator() { - return null; + return new ArrayListIterator(); + } + //create a private helper + private class ArrayListIterator implements Iterator { + + private int i; + private void ArrayListIterator(){ + 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 E next() { + if (i > size){ + throw new NoSuchElementException("i is now out of bounds"); + } + E currentValue = buffer[i]; + i++; + return currentValue; + } + } } diff --git a/test/ArrayListTest.java b/test/ArrayListTest.java index dbb3211..b0017c3 100644 --- a/test/ArrayListTest.java +++ b/test/ArrayListTest.java @@ -1,7 +1,18 @@ +import org.junit.jupiter.api.BeforeEach; + import static org.junit.jupiter.api.Assertions.*; class ArrayListTest { - + private ArrayList fullList; + private ArrayList emptyList; + @BeforeEach + void setUp(){ + emptyList = new ArrayList<>(); + fullList = new ArrayList<>(); + for (int i = 10; i > 0; i--) { + fullList.addFront(i-1); + } + } @org.junit.jupiter.api.Test void addFront() { ArrayList list = new ArrayList(); @@ -20,6 +31,9 @@ void addFront() { list.addFront(8); list.addFront(9); assertEquals(9,list.get(0)); + + fullList.addFront(1); + assertEquals(1, fullList.get(0)); } @org.junit.jupiter.api.Test @@ -39,6 +53,9 @@ void addBack() { list.addBack(9); list.addBack(10); assertEquals(10,list.get(list.size()-1)); + + fullList.addBack(1); + assertEquals(1, fullList.get(fullList.size()-1)); } @org.junit.jupiter.api.Test @@ -61,6 +78,9 @@ void add() { assertEquals(0,list.get(0)); assertEquals(10,list.get(10)); assertEquals(11,list.get(11)); + + fullList.add(10,1); + assertEquals(1, fullList.get(10)); } @org.junit.jupiter.api.Test @@ -83,6 +103,9 @@ void get() { assertEquals(1,list.get(1)); assertEquals(11,list.get(11)); //list.get(-1); //throws IndexOutOfBoundsException: Index cannot be negative + + + assertEquals(1, fullList.get(1)); } @org.junit.jupiter.api.Test @@ -105,6 +128,9 @@ void set() { list.add(11,11); list.set(11,100); assertEquals(100, list.get(11)); + + fullList.set(1,10); + assertEquals(10, fullList.get(1)); } @org.junit.jupiter.api.Test @@ -134,6 +160,9 @@ void removeFront() { list.add(9,11); list.removeFront(); assertEquals(3,list.get(0)); + + fullList.removeFront(); + assertEquals(1, fullList.get(0)); } @org.junit.jupiter.api.Test @@ -149,6 +178,9 @@ void removeBack() { list.removeBack(); assertEquals(2, list.get(list.size()-1)); assertEquals(2, list.removeBack()); + + fullList.removeBack(); + assertEquals(8, fullList.get(fullList.size()-1)); } @org.junit.jupiter.api.Test @@ -159,6 +191,9 @@ void remove() { list.add(2,3); list.remove("2"); assertFalse(list.contains("2")); + + fullList.remove(Integer.valueOf("1")); + assertFalse(fullList.contains(1)); } @org.junit.jupiter.api.Test @@ -179,6 +214,9 @@ void testRemove() { list.remove(7); assertEquals(7,list.get(list.size()-1)); + fullList.remove(1); + assertEquals(2, fullList.get(1)); + } @org.junit.jupiter.api.Test @@ -190,10 +228,15 @@ void contains() { list.add(2,2); assertTrue( list.contains(1)); assertTrue(list.contains(2)); + + + assertTrue(fullList.contains(1)); } @org.junit.jupiter.api.Test void isEmpty() { + assertTrue(emptyList.isEmpty()); + assertFalse(fullList.isEmpty()); } @org.junit.jupiter.api.Test @@ -206,9 +249,8 @@ void size() { assertEquals(2,list.size()); //list.removeFront(); //assertEquals(1,list.size()); + assertEquals(0,emptyList.size()); + assertEquals(10,fullList.size()); } - @org.junit.jupiter.api.Test - void iterator() { - } } \ No newline at end of file From cb249b1a3fec41e2f511e172abf3553a82753f88 Mon Sep 17 00:00:00 2001 From: kayleyyoung253 Date: Wed, 21 Feb 2024 20:48:05 -0800 Subject: [PATCH 06/18] completed contains, remove, removeBack, RemoveFront, set, add, addBack, addFront --- src/LinkedList.java | 341 +++++++++++++++++++++++++++++++++++++++ test/LinkedListTest.java | 226 ++++++++++++++++++++++++++ 2 files changed, 567 insertions(+) create mode 100644 src/LinkedList.java create mode 100644 test/LinkedListTest.java diff --git a/src/LinkedList.java b/src/LinkedList.java new file mode 100644 index 0000000..a3c438f --- /dev/null +++ b/src/LinkedList.java @@ -0,0 +1,341 @@ +import java.util.Iterator; + +public class LinkedList implements List { + //set up the head + private Node head; + + // set up the head field + private int size; + private class Node { + E data; + Node next; + public Node(E value){ + this.data=value; + } + + } + public LinkedList(){ + head = null; + size = 0; + } + + + /** + * Add item to the front. + * + * O(1) because regardless of the size of the linked list, + * all actions take constant time. + * + * @param item the item to be added + */ + @Override + public void addFront(E item) { + // set up a new node + Node theNewOne = new Node(item); + + if (head == null){ + //the list is currently empty + head = theNewOne; + size++; + } + else{ + // the list currently has some nodes in it + theNewOne.next = head; + head = theNewOne; + size++; + } + } + + /** + * Add item to the back. + * in the worst case scenario + * this code is O(n) where n is the number of nodes in the linked list. + * we need to traverse through the entire + * linked list to reach the end and add the new node. + * + * @param item the item to be added + */ + @Override + public void addBack(E item) { + Node newNode = new Node(item); + if (head == null) { + head = newNode; + } else { + Node current = head; + while (current.next != null) { + current = current.next; + } + current.next = newNode; + } + size++; + } + + /** + * Add an item at specified index (position). + * + * in the worst case scenario + * this code is O(n) where n is the size of the linked list. + * worst case - have to iterate through the entire + * linked list to find the correct position to insert the new node. + * + * @param i the index where the item should be added + * @param item the item to be added + */ + @Override + public void add(int i, E item) { + if(i < 0){ + throw new IndexOutOfBoundsException("Index cannot be negative"); + } + else if (i >= size){ + throw new IndexOutOfBoundsException("Index is higher than size"); + } + Node newNode = new Node(item); + if (i == 0) { + newNode.next = head; + head = newNode; + } else { + Node current = head; + for (int j = 0; j < i - 1; j++) { + current = current.next; + } + newNode.next = current.next; + current.next = newNode; + } + size++; + + } + + /** + * Get the item at a specified index + * . + * O(n) where n is the index i. This is because the code + * iterates through the linked list nodes until it reaches the node at index i. + * + * @param i the index where the item should be retrieved + * @return the item located at that index + */ + @Override + public E get(int i) { + Node current = head; + if(i < 0){ + throw new IndexOutOfBoundsException("Index cannot be negative"); + } + else if (i >= size){ + throw new IndexOutOfBoundsException("Index is higher than size"); + } + for (int j = 0; j < i; j++) { + current = current.next; + } + + return current.data; + } + + /** + * Set (save) an item at a specified index. Previous + * item at that index is overwritten. + * + * O(n) where n is the index i. This is because the code + * iterates through the linked list nodes until it reaches the node at index i. + * + * @param i the index where the item should be saved + * @param item the item to be saved + */ + @Override + public void set(int i, E item) { + if(i < 0){ + throw new IndexOutOfBoundsException("Index cannot be negative"); + } + else if (i >= size){ + throw new IndexOutOfBoundsException("Index is higher than size"); + } + + Node current = head; + for (int j = 0; j < i; j++) { + current = current.next; + } + current.data = item; + } + + /** + * Remove item at the front of the list. + * + * this method is O(1) because it performs a constant + * number of operations regardless of the size of the linked list. + * + * @return the item that was removed + */ + @Override + public E removeFront() { + if(head == null){ + //if there is nothing to delete + throw new IndexOutOfBoundsException("Array is empty"); + } + + E removedItem = head.data; + if (head.data == null) { + head = null; + } else { + head = head.next; + } + size--; + return removedItem; + } + + /** + * Remove item at the back of the list + * + * this code is O(n) because we would need to traverse + * through the entire linked list to find the second to last node. + * + * @return the item that was removed + */ + @Override + public E removeBack() { + Node current = head; + E removedItem = current.data; + if(current == null){ + //if there is nothing to delete + throw new IndexOutOfBoundsException("Array is empty"); + } + if(current.next == null){ + //if there is only 1 value in the array + removedItem = head.data; + current = null; + + }else{ + //for traversing the list to the second to last node, then remove current.next + while (current.next.next !=null){ + current = current.next; + } + removedItem = current.next.data; + current.next = null; + + } + size--; + return removedItem; + + + } + + /** + * Remove item from the list + * + * in the worst case scenario, this code is O(n) + * we may have to iterate through all the + * elements in the linked list to find and delete the specified item. + * + * @param item the item to be removed + */ + @Override + public void remove(E item) { + Node current = head; + if(current == null){ + //if there is nothing to delete + throw new IndexOutOfBoundsException("Array is empty"); + } + // Handle case where item is at the beginning of the list + while (head != null && head.data.equals(item)) { + head = head.next; + + } + while (current != null && current.next != null) { + if (current.next.data.equals(item)) { + current.next = current.next.next; + + } + else { + current = current.next; + } + } + size--; + + } + + /** + * Remove item at a specified index. + * + * in the worst case scenario, this code is O(n) + * we may have to iterate through n + * elements in the linked list to find and delete the specified item at index listed. + * + * @param i the index where the item should be removed + * @return the item that was removed + */ + @Override + public E remove(int i) { + Node current = head; + E removed;//keep track of the removed value + if(i < 0){ + throw new IndexOutOfBoundsException("Index cannot be negative"); + } + else if (i >= size){ + throw new IndexOutOfBoundsException("Index is higher than size"); + } + if(i == 0){ + removed = head.data; + head = head.next; + + }else{ + for (int j = 0; j < i - 1; j++) { + current = current.next; + } + + removed = current.next.data; + current.next = current.next.next; + size--; + } + + return removed; + } + + /** + * Checks if an item is in the list. + * + * @param item the item to search for + * @return true if the item is in the list, false otherwise + */ + @Override + public boolean contains(E item) { + Node current = head;//traverse the list from start to finish + if(current == null){ + throw new IndexOutOfBoundsException("Array is empty"); + } + while(current!= null){ + if(current.data.equals(item)){ + return true; + } + current = current.next; + } + return false; + } + + /** + * Checks if the list is empty. + * + * @return true if the list is empty, false otherwise + */ + @Override + public boolean isEmpty() { + return false; + } + + /** + * Provides a count of the number of items in the list. + * + * @return number of items in the list + */ + @Override + public int size() { + return 0; + } + + /** + * Returns an iterator over elements of type {@code T}. + * + * @return an Iterator. + */ + @Override + public Iterator iterator() { + return null; + } +} diff --git a/test/LinkedListTest.java b/test/LinkedListTest.java new file mode 100644 index 0000000..1dd91b6 --- /dev/null +++ b/test/LinkedListTest.java @@ -0,0 +1,226 @@ +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.lang.reflect.Array; + +import static org.junit.jupiter.api.Assertions.*; + +class LinkedListTest { + private ArrayList fullList = new ArrayList<>(); + private ArrayList oneList = new ArrayList<>(); + private ArrayList emptyList = new ArrayList<>(); + String A = "1"; + @BeforeEach + void setUp(){ + oneList.addFront("A"); + for (int i = 10; i > 0; i--) { + fullList.addFront(i-1); + } + } + @Test + void addFront() { + emptyList.addFront((E)A); + assertEquals((E)"1",emptyList.get(0)); + emptyList.addFront((E) "B"); + assertEquals((E) "1", emptyList.get(1)); + assertEquals((E)"B",emptyList.get(0)); + + oneList.addFront("A"); + assertEquals("A",oneList.get(0)); + + fullList.addFront(10); + assertEquals(10, fullList.get(0)); + fullList.addFront(11); + fullList.addFront(12); + assertEquals(12,fullList.get(0)); + assertEquals(11,fullList.get(1)); + + } + + @Test + void addBack() { + emptyList.addBack((E)A); + assertEquals((E)"1",emptyList.get(0)); + emptyList.addBack((E) "B"); + assertEquals((E) "B", emptyList.get(1)); + assertEquals((E)"1",emptyList.get(0)); + + oneList.addBack("A"); + assertEquals("A",oneList.get(1)); + + fullList.addBack(10); + assertEquals(10, fullList.get(10)); + fullList.addBack(11); + fullList.addBack(12); + assertEquals(12,fullList.get(12)); + assertEquals(11,fullList.get(11)); + } + + @Test + void add() { + emptyList.add(0,(E)A); + assertEquals((E)"1",emptyList.get(0)); + emptyList.add(1, (E) "B"); + assertEquals((E) "B", emptyList.get(1)); + assertEquals((E)"1",emptyList.get(0)); + + //oneList.add(2,("A")); + //assertEquals("A",oneList.get(2));// index is higher than size + oneList.add(1,"A"); + assertEquals("A",oneList.get(1)); + + fullList.add(2,10); + assertEquals(10, fullList.get(2)); + fullList.add(10,10); + fullList.add(12,12); + assertEquals(12,fullList.get(12)); + assertEquals(10,fullList.get(10)); + } + + @Test + void get() { + } + + @Test + void set() { + emptyList.addFront((E)A); + assertEquals((E)"1",emptyList.get(0)); + emptyList.set(0,(E) "B"); + assertEquals((E)"B",emptyList.get(0)); + emptyList.addFront((E) "C"); + emptyList.set(0,(E)"A"); + assertEquals((E) "A", emptyList.get(0)); + + oneList.set(0, "B"); + assertEquals("B",oneList.get(0)); + oneList.addFront("C"); + oneList.set(0, "A"); + assertEquals("A",oneList.get(0)); + oneList.set(1, "B"); + assertEquals( "B", oneList.get(1)); + + fullList.set(0, 1); + assertEquals(1,fullList.get(0)); + } + + @Test + void removeFront() { + // emptyList.removeFront();//throws "Array is empty, nothing to remove + emptyList.addFront((E) "C"); + emptyList.addFront((E) "B"); + emptyList.removeFront(); + assertEquals((E)"C",emptyList.get(0)); + + oneList.addFront( "C"); + oneList.addFront( "B"); + oneList.removeFront(); + assertEquals("C",oneList.get(0)); + + fullList.removeFront(); + assertEquals(1, fullList.get(0)); + fullList.add(9,9); + fullList.add(10,10); + fullList.removeFront(); + assertEquals(2,fullList.get(0)); + assertEquals(10,fullList.get(9)); + } + + @Test + void removeBack() { + // emptyList.removeFront();//throws "Array is empty, nothing to remove + emptyList.addFront((E) "C"); + emptyList.addFront((E) "B"); + emptyList.removeBack(); + assertEquals((E)"B",emptyList.get(0)); + + oneList.addFront( "C"); + oneList.addFront( "B"); + oneList.removeBack(); + assertEquals("B",oneList.get(0)); + + fullList.removeBack(); + assertEquals(9, fullList.size()); + fullList.add(9,9); + fullList.add(10,10); + fullList.removeBack(); + assertEquals(9,fullList.get(9)); + assertEquals(0,fullList.get(0)); + } + + @Test + void remove() { + // emptyList.remove();//throws "Array is empty, nothing to remove + emptyList.addFront((E) "C"); + emptyList.addFront((E) "B"); + emptyList.remove((E)"B"); + assertEquals((E)"C",emptyList.get(0)); + + oneList.remove("A"); + assertEquals(0,oneList.size()); + oneList.addFront( "C"); + oneList.addFront( "B"); + oneList.remove("B"); + assertEquals("C",oneList.get(0)); + + fullList.remove(1); + assertEquals(9, fullList.size()); + assertEquals(2,fullList.get(1)); + fullList.add(9,9); + fullList.add(10,10); + fullList.remove(9); + assertEquals(10,fullList.get(9)); + assertEquals(0,fullList.get(0)); + + } + + @Test + void testRemove() { + // emptyList.remove(0);//throws "Array is empty, nothing to remove + emptyList.addFront((E) "C"); + emptyList.addFront((E) "B"); + emptyList.remove((E)"B"); + assertEquals((E)"C",emptyList.get(0)); + emptyList.addFront((E) "C"); + emptyList.addFront((E) "B"); + emptyList.remove(0); + assertEquals((E)"C",emptyList.get(0)); + + oneList.remove(0); + assertEquals(0,oneList.size()); + oneList.addFront( "C"); + oneList.addFront( "B"); + oneList.remove(1); + assertEquals(1,oneList.size()); + assertEquals("B",oneList.get(0)); + + fullList.remove( 9); + assertEquals(9, fullList.size()); + assertEquals(1,fullList.get(1)); + // assertEquals(9,fullList.get(9));//"Index is higher than size, node where 9 used to be + fullList.add(9,9); + fullList.add(10,10); + fullList.remove(9); + assertEquals(10,fullList.get(9)); + assertEquals(0,fullList.get(0)); + } + + @Test + void contains() { + assertFalse(emptyList.contains((E) "C")); + emptyList.addFront((E) "B"); + assertEquals((E)"B",emptyList.get(0)); + assertTrue(emptyList.contains((E)"B")); + emptyList.addFront((E) "C"); + emptyList.addFront((E) "D"); + emptyList.remove(0); + assertFalse(emptyList.contains((E)"D")); + } + + @Test + void isEmpty() { + } + + @Test + void size() { + } +} \ No newline at end of file From 5653335f86d53a1c36905401aa87af87dd7abf8d Mon Sep 17 00:00:00 2001 From: kayleyyoung253 Date: Wed, 21 Feb 2024 21:13:27 -0800 Subject: [PATCH 07/18] completed the rest of the methods and all their tests --- src/LinkedList.java | 146 ++++++++++++++++++++++++++------------- test/LinkedListTest.java | 23 ++++++ 2 files changed, 121 insertions(+), 48 deletions(-) diff --git a/src/LinkedList.java b/src/LinkedList.java index a3c438f..9ed9ba8 100644 --- a/src/LinkedList.java +++ b/src/LinkedList.java @@ -1,20 +1,30 @@ import java.util.Iterator; +import java.util.NoSuchElementException; + +/** + * implement all of the methods in the List interface, and implement the interator() + * method from the iterable interface + * @author Kayley Young + */ public class LinkedList implements List { //set up the head private Node head; // set up the head field - private int size; + private int size; + private class Node { E data; Node next; - public Node(E value){ - this.data=value; + + public Node(E value) { + this.data = value; } } - public LinkedList(){ + + public LinkedList() { head = null; size = 0; } @@ -33,12 +43,11 @@ public void addFront(E item) { // set up a new node Node theNewOne = new Node(item); - if (head == null){ + if (head == null) { //the list is currently empty head = theNewOne; size++; - } - else{ + } else { // the list currently has some nodes in it theNewOne.next = head; head = theNewOne; @@ -83,10 +92,9 @@ public void addBack(E item) { */ @Override public void add(int i, E item) { - if(i < 0){ + if (i < 0) { throw new IndexOutOfBoundsException("Index cannot be negative"); - } - else if (i >= size){ + } else if (i >= size) { throw new IndexOutOfBoundsException("Index is higher than size"); } Node newNode = new Node(item); @@ -108,8 +116,8 @@ else if (i >= size){ /** * Get the item at a specified index * . - * O(n) where n is the index i. This is because the code - * iterates through the linked list nodes until it reaches the node at index i. + * O(n) where n is the index i. This is because the code + * iterates through the linked list nodes until it reaches the node at index i. * * @param i the index where the item should be retrieved * @return the item located at that index @@ -117,10 +125,9 @@ else if (i >= size){ @Override public E get(int i) { Node current = head; - if(i < 0){ + if (i < 0) { throw new IndexOutOfBoundsException("Index cannot be negative"); - } - else if (i >= size){ + } else if (i >= size) { throw new IndexOutOfBoundsException("Index is higher than size"); } for (int j = 0; j < i; j++) { @@ -134,18 +141,17 @@ else if (i >= size){ * Set (save) an item at a specified index. Previous * item at that index is overwritten. * - * O(n) where n is the index i. This is because the code - * iterates through the linked list nodes until it reaches the node at index i. + * O(n) where n is the index i. This is because the code + * iterates through the linked list nodes until it reaches the node at index i. * * @param i the index where the item should be saved * @param item the item to be saved */ @Override public void set(int i, E item) { - if(i < 0){ + if (i < 0) { throw new IndexOutOfBoundsException("Index cannot be negative"); - } - else if (i >= size){ + } else if (i >= size) { throw new IndexOutOfBoundsException("Index is higher than size"); } @@ -159,14 +165,14 @@ else if (i >= size){ /** * Remove item at the front of the list. * - * this method is O(1) because it performs a constant - * number of operations regardless of the size of the linked list. + * this method is O(1) because it performs a constant + * number of operations regardless of the size of the linked list. * * @return the item that was removed */ @Override public E removeFront() { - if(head == null){ + if (head == null) { //if there is nothing to delete throw new IndexOutOfBoundsException("Array is empty"); } @@ -193,18 +199,18 @@ public E removeFront() { public E removeBack() { Node current = head; E removedItem = current.data; - if(current == null){ + if (current == null) { //if there is nothing to delete throw new IndexOutOfBoundsException("Array is empty"); } - if(current.next == null){ + if (current.next == null) { //if there is only 1 value in the array removedItem = head.data; current = null; - }else{ + } else { //for traversing the list to the second to last node, then remove current.next - while (current.next.next !=null){ + while (current.next.next != null) { current = current.next; } removedItem = current.next.data; @@ -220,16 +226,16 @@ public E removeBack() { /** * Remove item from the list * - * in the worst case scenario, this code is O(n) - * we may have to iterate through all the - * elements in the linked list to find and delete the specified item. + * in the worst case scenario, this code is O(n) + * we may have to iterate through all the + * elements in the linked list to find and delete the specified item. * * @param item the item to be removed */ @Override public void remove(E item) { Node current = head; - if(current == null){ + if (current == null) { //if there is nothing to delete throw new IndexOutOfBoundsException("Array is empty"); } @@ -242,8 +248,7 @@ public void remove(E item) { if (current.next.data.equals(item)) { current.next = current.next.next; - } - else { + } else { current = current.next; } } @@ -254,9 +259,9 @@ public void remove(E item) { /** * Remove item at a specified index. * - * in the worst case scenario, this code is O(n) - * we may have to iterate through n - * elements in the linked list to find and delete the specified item at index listed. + * in the worst case scenario, this code is O(n) + * we may have to iterate through n + * elements in the linked list to find and delete the specified item at index listed. * * @param i the index where the item should be removed * @return the item that was removed @@ -265,17 +270,16 @@ public void remove(E item) { public E remove(int i) { Node current = head; E removed;//keep track of the removed value - if(i < 0){ + if (i < 0) { throw new IndexOutOfBoundsException("Index cannot be negative"); - } - else if (i >= size){ + } else if (i >= size) { throw new IndexOutOfBoundsException("Index is higher than size"); } - if(i == 0){ + if (i == 0) { removed = head.data; head = head.next; - }else{ + } else { for (int j = 0; j < i - 1; j++) { current = current.next; } @@ -291,17 +295,21 @@ else if (i >= size){ /** * Checks if an item is in the list. * + * in the worst case scenario this code is O(n) + * n is the number of nodes in the linked list + * we may have to traverse the entire linked list to find the item we are looking for. + * * @param item the item to search for * @return true if the item is in the list, false otherwise */ @Override public boolean contains(E item) { Node current = head;//traverse the list from start to finish - if(current == null){ + if (current == null) { throw new IndexOutOfBoundsException("Array is empty"); } - while(current!= null){ - if(current.data.equals(item)){ + while (current != null) { + if (current.data.equals(item)) { return true; } current = current.next; @@ -312,30 +320,72 @@ public boolean contains(E item) { /** * Checks if the list is empty. * + * O(1) because its only a single comparison + * to check if the size variable is equal to 0. + * * @return true if the list is empty, false otherwise */ @Override public boolean isEmpty() { - return false; + return size == 0; } /** * Provides a count of the number of items in the list. * + * O(1) because its only a single comparison + * to check the size + * * @return number of items in the list */ @Override public int size() { - return 0; + return size; } /** * Returns an iterator over elements of type {@code T}. * + * this method would be O(1) this is constant time complexity. + * it creates a new instance of the LinkedListIterator class and returns it. + * this involves simple operations that do not depend on the size of the linked list. + * * @return an Iterator. */ @Override public Iterator iterator() { - return null; + return new LinkedListIterator(); + } + + private class LinkedListIterator implements Iterator { + private Node 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() { + return current != null; + } + + /** + * 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 E next() { + if (!hasNext()) { + throw new NoSuchElementException("there is no next one to go to"); + } + E data = current.data; + current = current.next; + return data; + } } -} +} \ No newline at end of file diff --git a/test/LinkedListTest.java b/test/LinkedListTest.java index 1dd91b6..708e709 100644 --- a/test/LinkedListTest.java +++ b/test/LinkedListTest.java @@ -214,13 +214,36 @@ void contains() { emptyList.addFront((E) "D"); emptyList.remove(0); assertFalse(emptyList.contains((E)"D")); + + assertFalse(oneList.contains("B")); + oneList.addFront( "C"); + oneList.addFront( "D"); + oneList.remove(1); + assertTrue(oneList.contains("D")); + assertFalse(oneList.contains("C")); + + fullList.remove( 9); + assertEquals(9, fullList.size()); + assertFalse(fullList.contains(9)); + + fullList.add(9,9); + assertTrue(fullList.contains(9)); + fullList.add(10,10); + assertTrue(fullList.contains(10)); + assertFalse(fullList.contains(20)); } @Test void isEmpty() { + assertTrue(emptyList.isEmpty()); + assertFalse(oneList.isEmpty()); + assertFalse(fullList.isEmpty()); } @Test void size() { + assertEquals(0,emptyList.size()); + assertEquals(1,oneList.size()); + assertEquals(10,fullList.size()); } } \ No newline at end of file From 2cf28cf507ecd5e32e424c45d29d0df0429394d1 Mon Sep 17 00:00:00 2001 From: kayleyyoung253 Date: Wed, 21 Feb 2024 21:30:22 -0800 Subject: [PATCH 08/18] created Bag.java interface file --- src/Bag.java | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 src/Bag.java diff --git a/src/Bag.java b/src/Bag.java new file mode 100644 index 0000000..643b293 --- /dev/null +++ b/src/Bag.java @@ -0,0 +1,6 @@ +/** + * (collection of unordered items) Bag API + * @param class / data type of the items in the bag + */ +public interface Bag extends Iterable { +} From 43558f2af9ff819417f1196203645def0ae87149 Mon Sep 17 00:00:00 2001 From: kayleyyoung253 Date: Thu, 22 Feb 2024 08:54:54 -0800 Subject: [PATCH 09/18] created Bag.java interface file --- src/Bag.java | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/Bag.java b/src/Bag.java index 643b293..cceb55a 100644 --- a/src/Bag.java +++ b/src/Bag.java @@ -3,4 +3,23 @@ * @param class / data type of the items in the bag */ public interface Bag extends Iterable { + /** + * Add an item to the bag + * @param item the item to be added + */ + void add(E item); + + /** + * Checks if the bag is empty or not + * @return true if the bag is empty, false otherwise + */ + boolean isEmpty(); + + /** + * Returns the number of items in the bag + * @return the number of items in the bag + */ + int size(); + + } From f2c2a31a69cde4814592c4cc50089633278a1879 Mon Sep 17 00:00:00 2001 From: kayleyyoung253 Date: Thu, 22 Feb 2024 08:55:59 -0800 Subject: [PATCH 10/18] created Bag.java interface file --- src/Bag.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Bag.java b/src/Bag.java index cceb55a..8138523 100644 --- a/src/Bag.java +++ b/src/Bag.java @@ -1,11 +1,11 @@ /** - * (collection of unordered items) Bag API + * A collection of unordered items the Bag API - Bag.java * @param class / data type of the items in the bag */ public interface Bag extends Iterable { /** * Add an item to the bag - * @param item the item to be added + * @param item (the item to be added) */ void add(E item); From 13f2e7f5429be3f27fac75cc09a24123dfd7688d Mon Sep 17 00:00:00 2001 From: kayleyyoung253 Date: Thu, 22 Feb 2024 17:27:45 -0800 Subject: [PATCH 11/18] created test client with main method --- src/StackTestClient.java | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 src/StackTestClient.java diff --git a/src/StackTestClient.java b/src/StackTestClient.java new file mode 100644 index 0000000..e6b77a4 --- /dev/null +++ b/src/StackTestClient.java @@ -0,0 +1,21 @@ +import java.util.Scanner; +public class StackTestClient { + + public static void main(String[] args) { + Stack s = new ResizingArrayStack(); + Scanner in = new Scanner("to be or not to - be - - that - - - is"); + while (in.hasNext()) { + String item = in.next(); + + if (!item.equals("-")) { + s.push(item); + } + else if (!s.isEmpty()) { + System.out.println(s.pop() + " "); + } + + } + System.out.println("(" + s.size() + " left on the stack)"); + } + +} From b63314faf412931cce93d3ae29408d2734c7d334 Mon Sep 17 00:00:00 2001 From: kayleyyoung253 Date: Fri, 23 Feb 2024 21:34:37 -0800 Subject: [PATCH 12/18] created stack implementation with push, pop, peek, isEmpty, size, and iterator --- src/ResizingArrayStack.java | 153 ++++++++++++++++++++++++++++++++++++ src/StackTestClient.java | 2 +- 2 files changed, 154 insertions(+), 1 deletion(-) create mode 100644 src/ResizingArrayStack.java diff --git a/src/ResizingArrayStack.java b/src/ResizingArrayStack.java new file mode 100644 index 0000000..ee5a312 --- /dev/null +++ b/src/ResizingArrayStack.java @@ -0,0 +1,153 @@ +import java.util.Iterator; +import java.util.NoSuchElementException; + +/** + * + * implement all of the methods in the Stack interface, and implement the interator() + * method from the iterable interface + * @author Kayley Young + */ + +public class ResizingArrayStack implements Stack { + private E[] buffer; + private int size; + private static final int SIZE = 10; + /** + * constructor initializes the fields. + */ + public ResizingArrayStack() { + this.buffer = (E[]) new Object[SIZE]; + this.size = 0; + } + + /** + * resizes array by placing items in old array into new array + * @param max + */ + public void resize(int max){ + E[] newBuffer = (E[]) new Object[max]; + //copy everything over from buffer into newBuffer + for (int i = 0; i < size; i++) { + newBuffer[i] = buffer[i]; + } + // + buffer = newBuffer; + } + /** + * Add an item to the stack. + * + * This method runs in O(1) because with single operations the complexity class is constant. + * + * @param item the item to be added + */ + @Override + public void push(E item) { + //add item to top of stack + if (size == buffer.length){ + resize( 2 * buffer.length); + } + buffer[size++] = item; + + } + + /** + * Removes the most recently added item from the stack. + * + * This method runs in O(1) because with single operations the complexity class is constant. + * + * @return the item that was removed + */ + @Override + public E pop() { + if (isEmpty()){ + throw new IndexOutOfBoundsException("Stack is empty"); + } + E item = buffer[--size]; + //allow garbage collector to come by overwriting to null + buffer[size] = null; + if (size > 0 && size == buffer.length / 2){ + resize(buffer.length / 2); + } + return item; + } + + /** + * Returns the item at the top of the stack. + * Does not modify the stack or the item at the top. + * + * This method runs in O(1) because with single operations the complexity class is constant. + * + * @return item at the top of the stack. + */ + @Override + public E peek() { + if (isEmpty()){ + throw new IndexOutOfBoundsException("Stack is empty"); + } + return buffer[size - 1]; + } + + /** + * Checks to see if the stack is empty. + * + * This method runs in O(1) because with single comparison operation the complexity class is constant. + * + * @return true if the stack is empty, false otherwise + */ + @Override + public boolean isEmpty() { + return size == 0; + } + + /** + * Returns a count of the number of items in the stack. + * + * This method runs in O(1) because with single operations the complexity class is constant. + * + * @return the number of items in the stack + */ + @Override + public int size() { + return size; + } + + /** + * Returns an iterator over elements of type {@code T}. + * + * @return an Iterator. + */ + @Override + public Iterator iterator() { + return new ReverseArrayIterator(); + } + private class ReverseArrayIterator implements Iterator{ + + private int item = size; + + /** + * 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 item > 0; + } + + /** + * 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 E next() { + if (!hasNext()) { + throw new NoSuchElementException("No more elements in the iteration"); + } + return buffer[--item]; + } + } +} diff --git a/src/StackTestClient.java b/src/StackTestClient.java index e6b77a4..aca1b37 100644 --- a/src/StackTestClient.java +++ b/src/StackTestClient.java @@ -2,7 +2,7 @@ public class StackTestClient { public static void main(String[] args) { - Stack s = new ResizingArrayStack(); + Stack s = new ResizingArrayStack<>(); Scanner in = new Scanner("to be or not to - be - - that - - - is"); while (in.hasNext()) { String item = in.next(); From 7bb0f634f19702e2b66191c4b2e774fc4bb3b547 Mon Sep 17 00:00:00 2001 From: kayleyyoung253 Date: Fri, 23 Feb 2024 23:37:00 -0800 Subject: [PATCH 13/18] created linked-list implementation with a stack with push, pop, peek, isEmpty, size, and iterator --- src/LinkedStack.java | 141 +++++++++++++++++++++++++++++++++++++++ src/StackTestClient.java | 3 +- 2 files changed, 143 insertions(+), 1 deletion(-) create mode 100644 src/LinkedStack.java diff --git a/src/LinkedStack.java b/src/LinkedStack.java new file mode 100644 index 0000000..580fac9 --- /dev/null +++ b/src/LinkedStack.java @@ -0,0 +1,141 @@ +import java.util.Iterator; +import java.util.ListIterator; +import java.util.NoSuchElementException; + +/** + * 2C – Pushdown (LIFO) Stack (linked-list implementation + * @author Kayley Young + */ +public class LinkedStack implements Stack { + private Node head; + private int size; + private class Node { + E data; + Node next; + + } + public LinkedStack() { + this.head = null; + this.size = 0; + } + /** + * Add an item to the stack. + * + * This method runs in O(1) because with a constant number of operations the complexity class is constant. + * + * + * @param item the item to be added + */ + @Override + public void push(E item) { + //save a link to the list + Node theOldOne = head; + //create new node for the beginning + head = new Node(); + //save the instance variables in the new node + head.data = item; + head.next = theOldOne; + size++; + + } + + /** + * Removes the most recently added item from the stack. + * + * This method runs in O(1) because with a constant number of operations the complexity class is constant. + * + * @return the item that was removed + */ + @Override + public E pop() { + //save a link to the item being removed + E item = head.data; + //remove top of stack + head = head.next; + size--; + + //return item that was removed + return item; + } + + /** + * Returns the item at the top of the stack. + * Does not modify the stack or the item at the top. + * + * This method runs in O(1) because with a constant number of operations the complexity class is constant. + * + * @return item at the top of the stack. + */ + @Override + public E peek() { + return head.data; + } + + /** + * Checks to see if the stack is empty. + * + * This method runs in O(1) because with single operations the complexity class is constant. + * + * @return true if the stack is empty, false otherwise + */ + @Override + public boolean isEmpty() { + return head == null; + } + + /** + * Returns a count of the number of items in the stack. + * + * This method runs in O(1) because with single operations the complexity class is constant. + * + * @return the number of items in the stack + */ + @Override + public int size() { + return size; + } + + /** + * Returns an iterator over elements of type {@code T}. + * + * This method runs in O(n) because the iterator implementation iterates through each element in the linked list once, + * making the time complexity linear with respect to the number of elements in the list. + * + * @return an Iterator. + */ + @Override + public Iterator iterator() { + return new ListIterator(); + } + private class ListIterator implements Iterator{ + private Node 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() { + return current != null; + } + + /** + * 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 E next() { + if (!hasNext()) { + throw new NoSuchElementException("there is no next one to go to"); + } + E item = current.data; + current = current.next; + + return item; + } + } +} diff --git a/src/StackTestClient.java b/src/StackTestClient.java index aca1b37..7d534dd 100644 --- a/src/StackTestClient.java +++ b/src/StackTestClient.java @@ -2,7 +2,8 @@ public class StackTestClient { public static void main(String[] args) { - Stack s = new ResizingArrayStack<>(); + //Stack s = new ResizingArrayStack<>(); + Stack s = new LinkedStack<>(); Scanner in = new Scanner("to be or not to - be - - that - - - is"); while (in.hasNext()) { String item = in.next(); From f2e51e2df1ff788c18e4fa6e9462628e41e707a1 Mon Sep 17 00:00:00 2001 From: kayleyyoung253 Date: Fri, 23 Feb 2024 23:40:34 -0800 Subject: [PATCH 14/18] created class for a linked-list implementation with a Queue --- src/LinkedQueue.java | 59 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 src/LinkedQueue.java diff --git a/src/LinkedQueue.java b/src/LinkedQueue.java new file mode 100644 index 0000000..bfb086a --- /dev/null +++ b/src/LinkedQueue.java @@ -0,0 +1,59 @@ +import java.util.Iterator; +/** + * + * implement all the methods in the Queue interface + * + * (LIFO) Queue - Linked-list implementation + * @author Kayley Young + */ +public class LinkedQueue implements Queue { + /** + * Add an item to the queue. + * + * @param item the item to be added + */ + @Override + public void enqueue(E item) { + + } + + /** + * Remove an item from the queue. + * + * @return the item that was removed + */ + @Override + public E dequeue() { + return null; + } + + /** + * Checks to see if the queue is empty. + * + * @return true if the queue is empty, false otherwise + */ + @Override + public boolean isEmpty() { + return false; + } + + /** + * Returns a count of the number of items in the queue. + * + * @return the number of items in the queue + */ + @Override + public int size() { + return 0; + } + + /** + * Returns an iterator over elements of type {@code T}. + * + * @return an Iterator. + */ + @Override + public Iterator iterator() { + return null; + } +} From b1588148b09c2e01ee75ad49aff9c8d3569418a5 Mon Sep 17 00:00:00 2001 From: kayleyyoung253 Date: Sun, 25 Feb 2024 20:15:57 -0800 Subject: [PATCH 15/18] added java docs for constructor --- src/LinkedList.java | 11 ++++++++--- src/ResizingArrayStack.java | 2 ++ 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/LinkedList.java b/src/LinkedList.java index 9ed9ba8..fdee7c4 100644 --- a/src/LinkedList.java +++ b/src/LinkedList.java @@ -18,12 +18,17 @@ private class Node { E data; Node next; - public Node(E value) { - this.data = value; + public Node(E data) { + this.data = data; } } - + /** + * constructor for LinkedList, initializes fields + * + * O(1) because initializing fields take constant time. + * + */ public LinkedList() { head = null; size = 0; diff --git a/src/ResizingArrayStack.java b/src/ResizingArrayStack.java index ee5a312..23df0bc 100644 --- a/src/ResizingArrayStack.java +++ b/src/ResizingArrayStack.java @@ -5,6 +5,8 @@ * * implement all of the methods in the Stack interface, and implement the interator() * method from the iterable interface + * + * Pushdown (LIFO) Stack - resizing array implementation * @author Kayley Young */ From b520f3b0894c9076ed0b705eb85e23489031b80b Mon Sep 17 00:00:00 2001 From: kayleyyoung253 Date: Sun, 25 Feb 2024 20:16:57 -0800 Subject: [PATCH 16/18] created LinkedBag the implements Bag interface. Created Test client Stats for output --- src/LinkedBag.java | 125 +++++++++++++++++++++++++++++++++++++++++++++ src/Stats.java | 39 ++++++++++++++ 2 files changed, 164 insertions(+) create mode 100644 src/LinkedBag.java create mode 100644 src/Stats.java diff --git a/src/LinkedBag.java b/src/LinkedBag.java new file mode 100644 index 0000000..7f45068 --- /dev/null +++ b/src/LinkedBag.java @@ -0,0 +1,125 @@ +import java.util.Iterator; +import java.util.NoSuchElementException; + +/** + * + * implement all the methods in the Queue interface + * + * Bag- Linked-list implementation + * @author Kayley Young + */ +public class LinkedBag implements Bag { + private Node head; //first node in list + private int size; //number of items in bag + private class Node{ + E data; + Node next; + public Node(E data ){ + this.data = data; + } + } + /** + * constructor for LinkedBag initializes fields + * + * O(1) because initializing fields take constant time. + * + */ + public LinkedBag(){ + head = null; + size = 0; + + } + /** + * Add an item to the bag + * + * O(1) because regardless of the size of the linkedBag, + * all actions take constant time. + * + * @param item (the item to be added) + */ + @Override + public void add(E item) { + Node theNewOne = new Node(item); + + if (head == null) { + //the list is currently empty + head = theNewOne; + size++; + } else { + // the list currently has some nodes in it + theNewOne.next = head; + head = theNewOne; + size++; + } + } + + /** + * Checks if the bag is empty or not + * O(1) because it's only a single comparison + * to check if the size variable is equal to 0. + * + * @return true if the bag is empty, false otherwise + */ + @Override + public boolean isEmpty() { + return size == 0; + } + + /** + * Returns the number of items in the bag + * O(1) because it's only a single comparison + * to check the size + * + * @return the number of items in the bag + */ + @Override + public int size() { + return size; + } + + /** + * Returns an iterator over elements of type {@code T}. + * + * this method would be O(1) this is constant time complexity. + * it creates a new instance of the LinkedBagIterator class and returns it. + * this involves simple operations that do not depend on the size of the linkedBag. + * + * @return an Iterator. + */ + @Override + public Iterator iterator() { + return new LinkedBagIterator(); + } + + private class LinkedBagIterator implements Iterator { + private Node 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() { + return current != null; + } + + /** + * 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 E next() { + if (!hasNext()) { + throw new NoSuchElementException("there is no next one to go to"); + } + E data = current.data; + current = current.next; + return data; + } + } +} diff --git a/src/Stats.java b/src/Stats.java new file mode 100644 index 0000000..f5ed907 --- /dev/null +++ b/src/Stats.java @@ -0,0 +1,39 @@ +import java.util.Scanner; +/** + * + * Test the methods in the Bag interface + * Test client for LinkedBag + * + * Bag- Linked-list implementation + * @author Kayley Young + */ +public class Stats { + public static void main(String[] args) { + + Bag numbers = new LinkedBag<>(); + Scanner in = new Scanner("100 99 101 120 98 107 109 81 101 90"); + System.out.println("% java Stats"); + while (in.hasNextDouble()) { + double value = in.nextDouble(); + System.out.printf("%.0f%n", value); + numbers.add(value); + } + int item = numbers.size(); + + double sum = 0.0; + for (double x: numbers) { + sum += x; + } + double mean = sum/item; + + sum = 0.0; + for (double x: numbers) { + sum += (x - mean) * (x - mean); + } + double std = Math.sqrt(sum/(item-1)); + System.out.printf("\nMean: %.2f\n", mean); + System.out.printf("Std dev: %.2f\n", std); + + + } +} From 2ad36677132b4e84b5b901aa82b08e67505782b9 Mon Sep 17 00:00:00 2001 From: kayleyyoung253 Date: Sun, 25 Feb 2024 20:17:41 -0800 Subject: [PATCH 17/18] created LinkedQueue that implements Queue interface. Created QueueTestClient for output --- src/LinkedQueue.java | 129 +++++++++++++++++++++++++++++++++++++-- src/QueueTestClient.java | 23 +++++++ 2 files changed, 148 insertions(+), 4 deletions(-) create mode 100644 src/QueueTestClient.java diff --git a/src/LinkedQueue.java b/src/LinkedQueue.java index bfb086a..b991517 100644 --- a/src/LinkedQueue.java +++ b/src/LinkedQueue.java @@ -1,4 +1,7 @@ +import java.util.ConcurrentModificationException; import java.util.Iterator; +import java.util.NoSuchElementException; + /** * * implement all the methods in the Queue interface @@ -7,44 +10,108 @@ * @author Kayley Young */ public class LinkedQueue implements Queue { + private Node head; //link to least recently added node + private Node tail; //link to last node added in the queue + private int size; //number of items on the queue + private int numModifications; //the number of modifications made to the queue + + private class Node { + E item; + Node next; + + public Node(E item, Node next) { + this.item = item; + this.next = next; + } + } + /** + * constructor for LinkedQueue, initializes fields + * + * O(1) because initializing fields take constant time. + * + */ + public LinkedQueue() { + head = null; + tail = null; + size = 0; + numModifications = 0; + } /** * Add an item to the queue. * + * this method runs in O(1) because with single operations the complexity class is constant. + * * @param item the item to be added */ @Override public void enqueue(E item) { + if (item == null) { + throw new IllegalArgumentException("item is null"); + } + + Node oldTail = tail; + tail = new Node(item, null); + + if (isEmpty()) { + head = tail; + } + else { + oldTail.next = tail; + } + + size++; + numModifications++; } /** * Remove an item from the queue. * + * This method runs in O(1) because with single operations the complexity class is constant. + * * @return the item that was removed */ @Override public E dequeue() { - return null; + if (isEmpty()) { + throw new NoSuchElementException(); + } + + E item = head.item; + head = head.next; + + if (isEmpty()) { + tail = null; + } + + size--; + numModifications++; + + return item; } /** * Checks to see if the queue is empty. * + * This method runs in O(1) because with single comparison operation the complexity class is constant. + * * @return true if the queue is empty, false otherwise */ @Override public boolean isEmpty() { - return false; + return head == null; } /** * Returns a count of the number of items in the queue. * + * This method runs in O(1) because with single operations the complexity class is constant. + * * @return the number of items in the queue */ @Override public int size() { - return 0; + return size; } /** @@ -54,6 +121,60 @@ public int size() { */ @Override public Iterator iterator() { - return null; + return new LinkedListIterator(); + } + + private class LinkedListIterator implements Iterator { + private Node current; + private final int numModificationsAtCreation = numModifications; + + /** + * Initializes the iterator by setting the current + * position to be the same as the head (front) of + * the list. + */ + public LinkedListIterator() { + 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 + * @throws ConcurrentModificationException if queue has been modified since this iterator was created + */ + @Override + public boolean hasNext() { + if (numModifications != numModificationsAtCreation) { + throw new ConcurrentModificationException("queue has changed!"); + } + + return current != null; + } + + /** + * Returns the next element in the iteration. + * + * @return the next element in the iteration + * @throws NoSuchElementException if the iteration has no more elements + * @throws ConcurrentModificationException if the queue has been modified since this iterator was created + */ + @Override + public E next() { + if (numModifications != numModificationsAtCreation) { + throw new ConcurrentModificationException("queue has changed!"); + } + + if (current == null) { + throw new NoSuchElementException("current is null!"); + } + // save current.item so we can return it + E item = current.item; + // advance current to next node in list + current = current.next; + return item; + } } } diff --git a/src/QueueTestClient.java b/src/QueueTestClient.java new file mode 100644 index 0000000..ac11323 --- /dev/null +++ b/src/QueueTestClient.java @@ -0,0 +1,23 @@ +import java.util.Scanner; + +import java.util.Scanner; +public class QueueTestClient { + public static void main(String[] args) { + + Queue q = new LinkedQueue<>(); + Scanner in = new Scanner("to be or not to - be - - that - - - is"); + while (in.hasNext()) { + String item = in.next(); + + if (!item.equals("-")) { + q.enqueue(item); + } + else if (!q.isEmpty()) { + System.out.println(q.dequeue() + " "); + } + + } + System.out.println("(" + q.size() + " left on queue)"); + } + +} From 8ed86d811db308ca855b557eafd2f49a94a4e906 Mon Sep 17 00:00:00 2001 From: kayleyyoung253 Date: Sun, 25 Feb 2024 20:18:30 -0800 Subject: [PATCH 18/18] Created StackTestClient for output to test LinkedStack --- src/StackTestClient.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/StackTestClient.java b/src/StackTestClient.java index 7d534dd..b19aadf 100644 --- a/src/StackTestClient.java +++ b/src/StackTestClient.java @@ -1,4 +1,11 @@ import java.util.Scanner; +/** + * + * test the methods in the ResizingArrayStack and LinkedStack + * + * Linked-list implementation and resizing array + * @author Kayley Young + */ public class StackTestClient { public static void main(String[] args) {