From f5e8a473a53cf72867f4f197de2c905692476212 Mon Sep 17 00:00:00 2001 From: Gecervantes01 Date: Wed, 7 Feb 2024 11:42:05 -0800 Subject: [PATCH 1/7] Added test in main for ArrayList --- .idea/misc.xml | 1 - src/Main.java | 7 +++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/.idea/misc.xml b/.idea/misc.xml index 6f29fee..5af9c98 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,4 +1,3 @@ - diff --git a/src/Main.java b/src/Main.java index 8f8f984..4cb2cbc 100644 --- a/src/Main.java +++ b/src/Main.java @@ -6,5 +6,12 @@ public static void main(String[] args) { // to see how IntelliJ IDEA suggests fixing it. System.out.println("Hello and welcome!"); + ArrayList listTest = new ArrayList<>(); + listTest.addFront(21); + for(Integer i : listTest) { + System.out.println(i); + } + + } } \ No newline at end of file From c446c7d86c1cb7cff762b4851230d3e11207765c Mon Sep 17 00:00:00 2001 From: Gecervantes01 Date: Wed, 7 Feb 2024 11:42:19 -0800 Subject: [PATCH 2/7] Added test in main for ArrayList --- .idea/vcs.xml | 6 ++ src/ArrayList.java | 200 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 206 insertions(+) create mode 100644 .idea/vcs.xml create mode 100644 src/ArrayList.java diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/src/ArrayList.java b/src/ArrayList.java new file mode 100644 index 0000000..40f454a --- /dev/null +++ b/src/ArrayList.java @@ -0,0 +1,200 @@ +import java.util.Iterator; + +public class ArrayList implements List { + + private int size; + private E[] buffer; + + public ArrayList() { + buffer = (E[])new Object[10]; + size = 0; + } + + /** + * Add item to the front. + * + * @param item the item to be added + */ + @Override + public void addFront(E item) { + if(isEmpty()) { + buffer[0] = item; + } else { + for(int i = size; i > 0; i--) { + buffer[i] = buffer[i - 1]; + } + buffer[0] = item; + } + size++; + } + + /** + * Add item to the back. + * + * @param item the item to be added + */ + @Override + public void addBack(E item) { + if(size == buffer.length) { + + } else { + buffer[size] = item; + } + size++; + } + + /** + * 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) { + if(isEmpty()) { + throw new IndexOutOfBoundsException("List is empty."); + } else { + for(int j = size + 1; j > i; j--) { + buffer[j] = buffer[j - 1]; + } + buffer[i] = item; + size++; + } + + } + + /** + * 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) { + if(isEmpty()) { + throw new IndexOutOfBoundsException("List is empty."); + } else { + return buffer[i]; + } + } + + /** + * 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() { + if(isEmpty()) { + throw new IndexOutOfBoundsException("List is empty."); + } else { + E removedVal = buffer[0]; + for(int i = 0; i < size - 1; i++) { + buffer[i] = buffer[i + 1]; + } + size--; + return removedVal; + } + } + + /** + * Remove item at the back of the list + * + * @return the item that was removed + */ + @Override + public E removeBack() { + if(isEmpty()) { + throw new IndexOutOfBoundsException("List is empty."); + } else { + E removedVal = buffer[size - 1]; + buffer[size - 1] = null; + size--; + return removedVal; + } + } + + /** + * Remove item from the list + * + * @param item the item to be removed + */ + @Override + public void remove(E item) { + for(int i = 0; i < size; i++) { + if(buffer[i] == 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) { + for(E value : buffer) { + if(value == item) { + return true; + } + } + return false; + } + + /** + * Checks if the list is empty. + * + * @return true if the list is empty, false otherwise + */ + @Override + public boolean isEmpty() { + return size == 0; + } + + /** + * Provides a count of the number of items in the list. + * + * @return number of items in the list + */ + @Override + public int size() { + return size; + } + + /** + * Returns an iterator over elements of type {@code T}. + * + * @return an Iterator. + */ + @Override + public Iterator iterator() { + return null; + } +} From 99cc5e07366608f4acd7b691adc75d883edd7c00 Mon Sep 17 00:00:00 2001 From: Gecervantes01 Date: Wed, 7 Feb 2024 13:31:47 -0800 Subject: [PATCH 3/7] Finished both the ArrayList and LinkedList classes, created the test files (still need to write the tests). --- SDEV333-Term-Project.iml | 1 + src/ArrayList.java | 105 +++++++++++--- src/LinkedList.java | 290 ++++++++++++++++++++++++++++++++++++++ src/Main.java | 3 + tests/ArrayListTest.java | 56 ++++++++ tests/LinkedListTest.java | 58 ++++++++ 6 files changed, 495 insertions(+), 18 deletions(-) create mode 100644 src/LinkedList.java create mode 100644 tests/ArrayListTest.java create mode 100644 tests/LinkedListTest.java diff --git a/SDEV333-Term-Project.iml b/SDEV333-Term-Project.iml index c90834f..3506760 100644 --- a/SDEV333-Term-Project.iml +++ b/SDEV333-Term-Project.iml @@ -4,6 +4,7 @@ + diff --git a/src/ArrayList.java b/src/ArrayList.java index 40f454a..70730ed 100644 --- a/src/ArrayList.java +++ b/src/ArrayList.java @@ -1,4 +1,5 @@ import java.util.Iterator; +import java.util.NoSuchElementException; public class ArrayList implements List { @@ -17,14 +18,13 @@ public ArrayList() { */ @Override public void addFront(E item) { - if(isEmpty()) { - buffer[0] = item; - } else { - for(int i = size; i > 0; i--) { - buffer[i] = buffer[i - 1]; - } - buffer[0] = item; + if(size == buffer.length) { + increaseBuffer(); + } + for(int i = size; i > 0; i--) { + buffer[i] = buffer[i - 1]; } + buffer[0] = item; size++; } @@ -36,10 +36,9 @@ public void addFront(E item) { @Override public void addBack(E item) { if(size == buffer.length) { - - } else { - buffer[size] = item; + increaseBuffer(); } + buffer[size] = item; size++; } @@ -54,6 +53,9 @@ public void add(int i, E item) { if(isEmpty()) { throw new IndexOutOfBoundsException("List is empty."); } else { + if(size == buffer.length) { + increaseBuffer(); + } for(int j = size + 1; j > i; j--) { buffer[j] = buffer[j - 1]; } @@ -72,6 +74,8 @@ public void add(int i, E item) { @Override public E get(int i) { if(isEmpty()) { + throw new NoSuchElementException("List is empty, no values to return."); + } else if(i > size - 1|| i < 0) { throw new IndexOutOfBoundsException("List is empty."); } else { return buffer[i]; @@ -87,7 +91,11 @@ public E get(int i) { */ @Override public void set(int i, E item) { - + if(i > size - 1 || i < 0) { + throw new IndexOutOfBoundsException(); + } else { + buffer[i] = item; + } } /** @@ -133,12 +141,16 @@ public E removeBack() { */ @Override public void remove(E item) { - for(int i = 0; i < size; i++) { - if(buffer[i] == item) { - + if(isEmpty()) { + throw new NoSuchElementException("List is empty, no values to remove."); + } else { + for(int i = 0; i < size; i++) { + if(buffer[i].equals(item)) { + remove(i); + } } + size--; } - } /** @@ -149,7 +161,16 @@ public void remove(E item) { */ @Override public E remove(int i) { - return null; + if(isEmpty() || i > size - 1 || i < 0) { + throw new IndexOutOfBoundsException(); + } else { + E removedVal = buffer[i]; + for(int j = i; j < size - 1; j++) { + buffer[j] = buffer[j + 1]; + } + size--; + return removedVal; + } } /** @@ -161,7 +182,7 @@ public E remove(int i) { @Override public boolean contains(E item) { for(E value : buffer) { - if(value == item) { + if(value.equals(item)) { return true; } } @@ -188,6 +209,14 @@ public int size() { return size; } + private void increaseBuffer() { + E[] hold = (E[])new Object[buffer.length]; + if (size - 1 >= 0) System.arraycopy(buffer, 0, hold, 0, size - 1); + + buffer = (E[])new Object[buffer.length * 2]; + if (size - 1 >= 0) System.arraycopy(hold, 0, buffer, 0, size - 1); + } + /** * Returns an iterator over elements of type {@code T}. * @@ -195,6 +224,46 @@ public int size() { */ @Override public Iterator iterator() { - return null; + return new ArrayListIterator(); } + + public class ArrayListIterator implements Iterator { + + private int i; + + private 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(!hasNext()) { + throw new NoSuchElementException(); + } + E currentVal = buffer[i]; + i++; + return currentVal; + } + } + + + } diff --git a/src/LinkedList.java b/src/LinkedList.java new file mode 100644 index 0000000..31d486d --- /dev/null +++ b/src/LinkedList.java @@ -0,0 +1,290 @@ +import java.util.Iterator; +import java.util.NoSuchElementException; + +public class LinkedList implements List { + + private class Node { + E data; + Node next; + } + + private Node head; + private int size; + + public LinkedList() { + head = null; + size = 0; + } + + /** + * Add item to the front. + * + * @param item the item to be added + */ + @Override + public void addFront(E item) { + Node newNode = new Node(); + newNode.data = item; + newNode.next = head; + head = newNode; + size++; + } + + /** + * Add item to the back. + * + * @param item the item to be added + */ + @Override + public void addBack(E item) { + Node newNode = new Node(); + newNode.data = item; + if(head == null) { + head = newNode; + } else { + int counter = 0; + for(Node current = head; current.next != null; current = current.next) { + if(counter == size - 1) { + current.next = newNode; + break; + } + counter++; + } + } + size++; + } + + /** + * 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) { + if(isEmpty()) { + throw new IndexOutOfBoundsException("List is empty, value must be added to the front"); + } else if(i > size - 1 || i < 0) { + throw new IndexOutOfBoundsException("Invalid index."); + } + Node newNode = new Node(); + newNode.data = item; + int counter = 0; + for(Node current = head; current.next != null; current = current.next) { + if(counter == i - 1) { + newNode.next = current.next; + current.next = newNode; + size++; + } + counter++; + } + + } + + /** + * 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) { + if(isEmpty()) { + throw new NoSuchElementException("List is empty, no values to return."); + } else if (i > size - 1 || i < 0) { + throw new IndexOutOfBoundsException("Invalid index."); + } + int counter = 0; + E retreivedVal = null; + for(Node current = head; current.next != null; current = current.next) { + if(counter == i) { + retreivedVal = current.data; + } + counter++; + } + return retreivedVal; + } + + /** + * 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) { + if(isEmpty() && i > 0) { + throw new IndexOutOfBoundsException("List is empty, value must be placed at the front"); + } else if(i < 0 || i > size - 1) { + throw new IndexOutOfBoundsException("Invalid index"); + } + int counter = 0; + for(Node current = head; current.next != null; current = current.next) { + if(counter == i) { + current.data = item; + } + counter++; + } + } + + /** + * Remove item at the front of the list. + * + * @return the item that was removed + */ + @Override + public E removeFront() { + if(isEmpty()) { + throw new NoSuchElementException("List is empty, no values to remove."); + } + E removedVal = head.data; + head = head.next; + size--; + return removedVal; + } + + /** + * Remove item at the back of the list + * + * @return the item that was removed + */ + @Override + public E removeBack() { + if(isEmpty()) { + throw new NoSuchElementException("List is empty, no values to remove"); + } + E removedVal = null; + for(Node current = head; current.next != null; current = current.next) { + if(current.next.next == null) { + removedVal = current.next.data; + current.next = null; + size--; + } + } + return removedVal; + } + + /** + * Remove item from the list + * + * @param item the item to be removed + */ + @Override + public void remove(E item) { + for(Node current = head; current.next != null; current = current.next) { + if(current.next.data.equals(item)) { + current.next = current.next.next; + size--; + break; + } + } + } + + /** + * 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) { + if(isEmpty()) { + throw new NoSuchElementException("List is empty, no values to remove."); + } else if(i > size - 1 || i < 0) { + throw new IndexOutOfBoundsException(); + } + int counter = 0; + E removedVal = null; + for(Node current = head; current.next != null; current = current.next) { + if(counter == i - 1) { + removedVal = current.next.data; + current.next = current.next.next; + size--; + break; + } + counter++; + } + return removedVal; + } + + /** + * 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) { + for(Node current = head; current.next != null; current = current.next) { + if(current.data.equals(item)) { + return true; + } + } + return false; + } + + /** + * Checks if the list is empty. + * + * @return true if the list is empty, false otherwise + */ + @Override + public boolean isEmpty() { + return size == 0; + } + + /** + * Provides a count of the number of items in the list. + * + * @return number of items in the list + */ + @Override + public int size() { + return size; + } + + /** + * Returns an iterator over elements of type {@code T}. + * + * @return an Iterator. + */ + @Override + public Iterator iterator() { + return new LinkedListIterator(); + } + + public class LinkedListIterator implements Iterator { + + private Node current; + + private 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 + */ + @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() { + E val = current.data; + current = current.next; + return val; + } + } +} diff --git a/src/Main.java b/src/Main.java index 4cb2cbc..7c6b4f7 100644 --- a/src/Main.java +++ b/src/Main.java @@ -8,6 +8,9 @@ public static void main(String[] args) { ArrayList listTest = new ArrayList<>(); listTest.addFront(21); + listTest.addFront(20); + listTest.addFront(19); + for(Integer i : listTest) { System.out.println(i); } diff --git a/tests/ArrayListTest.java b/tests/ArrayListTest.java new file mode 100644 index 0000000..8fdc0ed --- /dev/null +++ b/tests/ArrayListTest.java @@ -0,0 +1,56 @@ +import static org.junit.jupiter.api.Assertions.*; + +class ArrayListTest { + + @org.junit.jupiter.api.Test + void addFront() { + } + + @org.junit.jupiter.api.Test + void addBack() { + } + + @org.junit.jupiter.api.Test + void add() { + } + + @org.junit.jupiter.api.Test + void get() { + } + + @org.junit.jupiter.api.Test + void set() { + } + + @org.junit.jupiter.api.Test + void removeFront() { + } + + @org.junit.jupiter.api.Test + void 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() { + } + + @org.junit.jupiter.api.Test + void iterator() { + } +} \ No newline at end of file diff --git a/tests/LinkedListTest.java b/tests/LinkedListTest.java new file mode 100644 index 0000000..f108bee --- /dev/null +++ b/tests/LinkedListTest.java @@ -0,0 +1,58 @@ +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +class LinkedListTest { + + @Test + void addFront() { + } + + @Test + void addBack() { + } + + @Test + void add() { + } + + @Test + void get() { + } + + @Test + void set() { + } + + @Test + void removeFront() { + } + + @Test + void removeBack() { + } + + @Test + void remove() { + } + + @Test + void testRemove() { + } + + @Test + void contains() { + } + + @Test + void isEmpty() { + } + + @Test + void size() { + } + + @Test + void iterator() { + } +} \ No newline at end of file From 2f10c20880e5278c8ab07bb2e6b15127bbc6d54a Mon Sep 17 00:00:00 2001 From: Gecervantes01 Date: Sun, 11 Feb 2024 14:01:40 -0800 Subject: [PATCH 4/7] Finished all tests --- SDEV333-Term-Project.iml | 26 ++++++++++ src/ArrayList.java | 60 ++++++++++++++++----- src/LinkedList.java | 48 +++++++++++++---- tests/ArrayListTest.java | 85 +++++++++++++++++++++++++++--- tests/LinkedListTest.java | 106 +++++++++++++++++++++++++++++++++++--- 5 files changed, 287 insertions(+), 38 deletions(-) diff --git a/SDEV333-Term-Project.iml b/SDEV333-Term-Project.iml index 3506760..9c8bf10 100644 --- a/SDEV333-Term-Project.iml +++ b/SDEV333-Term-Project.iml @@ -8,5 +8,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/ArrayList.java b/src/ArrayList.java index 70730ed..ab6a8b7 100644 --- a/src/ArrayList.java +++ b/src/ArrayList.java @@ -14,18 +14,20 @@ public ArrayList() { /** * Add item to the front. * + * Runtime analysis: O(N) + * * @param item the item to be added */ @Override public void addFront(E item) { - if(size == buffer.length) { - increaseBuffer(); + if(size == buffer.length) { // 1 + increaseBuffer(); // O(N) 5 + (8 * n) } - for(int i = size; i > 0; i--) { - buffer[i] = buffer[i - 1]; + for(int i = size; i > 0; i--) { // 6 * n + buffer[i] = buffer[i - 1]; // } - buffer[0] = item; - size++; + buffer[0] = item; // 1 + size++; // 2 } /** @@ -51,7 +53,12 @@ public void addBack(E item) { @Override public void add(int i, E item) { if(isEmpty()) { - throw new IndexOutOfBoundsException("List is empty."); + if(i == 0) { + buffer[i] = item; + size++; + } else { + throw new IndexOutOfBoundsException("List is empty."); + } } else { if(size == buffer.length) { increaseBuffer(); @@ -91,7 +98,14 @@ public E get(int i) { */ @Override public void set(int i, E item) { - if(i > size - 1 || i < 0) { + if(isEmpty()) { + if(i == 0) { + buffer[i] = item; + size++; + } else { + throw new NoSuchElementException("List is empty, must set first index."); + } + } else if(i > size - 1 || i < 0) { throw new IndexOutOfBoundsException(); } else { buffer[i] = item; @@ -176,13 +190,18 @@ public E remove(int i) { /** * Checks if an item is in the list. * + * Runtime Analysis: O(N) 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(E value : buffer) { - if(value.equals(item)) { + if(isEmpty()) { + return false; + } + for(int i = 0; i < size; i++) { + if(buffer[i].equals(item)) { return true; } } @@ -192,6 +211,8 @@ public boolean contains(E item) { /** * Checks if the list is empty. * + * Runtime Analysis: O(1) constant + * * @return true if the list is empty, false otherwise */ @Override @@ -202,6 +223,8 @@ public boolean isEmpty() { /** * Provides a count of the number of items in the list. * + * Runtime Analysis: O(1) constant + * * @return number of items in the list */ @Override @@ -209,12 +232,21 @@ public int size() { return size; } + + /** + * Runtime analysis: At it's worst it's O(N) linear. + */ + private void increaseBuffer() { - E[] hold = (E[])new Object[buffer.length]; - if (size - 1 >= 0) System.arraycopy(buffer, 0, hold, 0, size - 1); + E[] hold = (E[])new Object[buffer.length]; // 2 + for(int i = 0; i < size - 1; i++) { // 4 * n + hold[i] = buffer[i]; + } - buffer = (E[])new Object[buffer.length * 2]; - if (size - 1 >= 0) System.arraycopy(hold, 0, buffer, 0, size - 1); + buffer = (E[])new Object[buffer.length * 2]; // 3 + for(int i = 0; i < size - 1; i++) { // 4 * n + buffer[i] = hold[i]; + } } /** diff --git a/src/LinkedList.java b/src/LinkedList.java index 31d486d..b043f41 100644 --- a/src/LinkedList.java +++ b/src/LinkedList.java @@ -39,11 +39,13 @@ public void addFront(E item) { public void addBack(E item) { Node newNode = new Node(); newNode.data = item; - if(head == null) { + if(isEmpty()) { head = newNode; + } else if(size == 1) { + head.next = newNode; } else { int counter = 0; - for(Node current = head; current.next != null; current = current.next) { + for(Node current = head; current != null; current = current.next) { if(counter == size - 1) { current.next = newNode; break; @@ -62,7 +64,9 @@ public void addBack(E item) { */ @Override public void add(int i, E item) { - if(isEmpty()) { + if(i == 0) { + addFront(item); + } else if(isEmpty()) { throw new IndexOutOfBoundsException("List is empty, value must be added to the front"); } else if(i > size - 1 || i < 0) { throw new IndexOutOfBoundsException("Invalid index."); @@ -78,7 +82,6 @@ public void add(int i, E item) { } counter++; } - } /** @@ -93,10 +96,12 @@ public E get(int i) { throw new NoSuchElementException("List is empty, no values to return."); } else if (i > size - 1 || i < 0) { throw new IndexOutOfBoundsException("Invalid index."); + } else if(size == 1) { + return head.data; } int counter = 0; E retreivedVal = null; - for(Node current = head; current.next != null; current = current.next) { + for(Node current = head; current != null; current = current.next) { if(counter == i) { retreivedVal = current.data; } @@ -120,7 +125,7 @@ public void set(int i, E item) { throw new IndexOutOfBoundsException("Invalid index"); } int counter = 0; - for(Node current = head; current.next != null; current = current.next) { + for(Node current = head; current != null; current = current.next) { if(counter == i) { current.data = item; } @@ -151,11 +156,15 @@ public E removeFront() { */ @Override public E removeBack() { + E removedVal = null; if(isEmpty()) { throw new NoSuchElementException("List is empty, no values to remove"); + } else if (size == 1) { + removedVal = head.data; + head = null; + return removedVal; } - E removedVal = null; - for(Node current = head; current.next != null; current = current.next) { + for(Node current = head; current != null; current = current.next) { if(current.next.next == null) { removedVal = current.next.data; current.next = null; @@ -172,6 +181,14 @@ public E removeBack() { */ @Override public void remove(E item) { + if(isEmpty()) { + throw new NoSuchElementException("List is empty, no values to remove."); + } else if (size == 1) { + if(head.data.equals(item)) { + head.data = null; + size--; + } + } for(Node current = head; current.next != null; current = current.next) { if(current.next.data.equals(item)) { current.next = current.next.next; @@ -189,14 +206,20 @@ public void remove(E item) { */ @Override public E remove(int i) { + E removedVal = null; if(isEmpty()) { throw new NoSuchElementException("List is empty, no values to remove."); } else if(i > size - 1 || i < 0) { throw new IndexOutOfBoundsException(); + } else if(size == 1) { + removedVal = head.data; + head.data = null; + size--; + return removedVal; } int counter = 0; - E removedVal = null; - for(Node current = head; current.next != null; current = current.next) { + + for(Node current = head; current != null; current = current.next) { if(counter == i - 1) { removedVal = current.next.data; current.next = current.next.next; @@ -216,6 +239,11 @@ public E remove(int i) { */ @Override public boolean contains(E item) { + if(isEmpty()) { + return false; + } else if(size == 1) { + return head.data.equals(item); + } for(Node current = head; current.next != null; current = current.next) { if(current.data.equals(item)) { return true; diff --git a/tests/ArrayListTest.java b/tests/ArrayListTest.java index 8fdc0ed..51ab317 100644 --- a/tests/ArrayListTest.java +++ b/tests/ArrayListTest.java @@ -2,55 +2,124 @@ class ArrayListTest { + ArrayList emptyList = new ArrayList<>(); + ArrayList singleItemList = fillList(1); + ArrayList multiItemList = fillList(10); + + public ArrayList fillList(int size) { + ArrayList list = new ArrayList<>(); + for(int i = 0; i <= size - 1; i++) { + list.addBack(i + 1); + } + return list; + } + + @org.junit.jupiter.api.Test void addFront() { + assertTrue(emptyList.isEmpty()); + emptyList.addFront(30); + assertEquals(30, emptyList.get(0)); + + assertEquals(1, singleItemList.get(0)); + singleItemList.addFront(30); + assertEquals(30, singleItemList.get(0)); + + assertEquals(1, multiItemList.get(0)); + multiItemList.addFront(30); + assertEquals(30, multiItemList.get(0)); } @org.junit.jupiter.api.Test void addBack() { + assertTrue(emptyList.isEmpty()); + emptyList.addBack(30); + assertEquals(30, emptyList.get(emptyList.size() - 1)); + + assertEquals(1, singleItemList.get(singleItemList.size() - 1)); + singleItemList.addBack(30); + assertEquals(30, singleItemList.get(singleItemList.size() - 1)); + + assertEquals(10, multiItemList.get(multiItemList.size() - 1)); + multiItemList.addBack(30); + assertEquals(30, multiItemList.get(multiItemList.size() - 1)); } @org.junit.jupiter.api.Test void add() { + assertTrue(emptyList.isEmpty()); + emptyList.add(0,30); + assertEquals(30, emptyList.get(0)); + + assertFalse(singleItemList.contains(21)); + singleItemList.add(0, 21); + assertEquals(21, singleItemList.get(0)); + + assertEquals(6, multiItemList.get(5)); + multiItemList.add(5,30); + assertEquals(30, multiItemList.get(5)); + } @org.junit.jupiter.api.Test void get() { + // Unsure how to test for indexOutOfBounds exception + assertEquals(1, singleItemList.get(0)); + assertEquals(4, multiItemList.get(3)); } @org.junit.jupiter.api.Test void set() { + // Unsure how to test for indexOutOfBounds exception + + assertFalse(singleItemList.contains(35)); + singleItemList.set(0, 35); + assertEquals(35, singleItemList.get(0)); + + assertFalse(multiItemList.contains(21)); + multiItemList.set(5, 21); + assertEquals(21, multiItemList.get(5)); } @org.junit.jupiter.api.Test void removeFront() { + // Unsure how to test for indexOutOfBounds exception + assertEquals(1, singleItemList.removeFront()); + assertEquals(1, multiItemList.removeFront()); } @org.junit.jupiter.api.Test void removeBack() { + // Unsure how to test for indexOutOfBounds exception + assertEquals(1, singleItemList.removeBack()); + assertEquals(10, multiItemList.removeBack()); } @org.junit.jupiter.api.Test void remove() { - } - - @org.junit.jupiter.api.Test - void testRemove() { + // Unsure how to test for indexOutOfBounds exception + assertEquals(1, singleItemList.remove(0)); + assertEquals(7, multiItemList.remove(6)); } @org.junit.jupiter.api.Test void contains() { + assertFalse(emptyList.contains(2)); + assertTrue(singleItemList.contains(1)); + assertTrue(multiItemList.contains(6)); } @org.junit.jupiter.api.Test void isEmpty() { + assertTrue(emptyList.isEmpty()); + assertFalse(singleItemList.isEmpty()); + assertFalse(multiItemList.isEmpty()); } @org.junit.jupiter.api.Test void size() { - } - - @org.junit.jupiter.api.Test - void iterator() { + assertEquals(0, emptyList.size()); + assertEquals(1, singleItemList.size()); + assertEquals(10, multiItemList.size()); } } \ No newline at end of file diff --git a/tests/LinkedListTest.java b/tests/LinkedListTest.java index f108bee..317c5a3 100644 --- a/tests/LinkedListTest.java +++ b/tests/LinkedListTest.java @@ -4,55 +4,149 @@ class LinkedListTest { + LinkedList emptyList = new LinkedList<>(); + LinkedList singleItem = fillList(1); + LinkedList multiItem = fillList(10); + + public LinkedList fillList(int num) { + LinkedList list = new LinkedList<>(); + for(int i = num; i > 0; i--) { + list.addFront(i); + } + return list; + } + @Test void addFront() { + assertEquals(0, emptyList.size()); + emptyList.addFront(27); + assertEquals(27, emptyList.get(0)); + + assertEquals(1, singleItem.get(0)); + singleItem.addFront(21); + assertEquals(21, singleItem.get(0)); + + assertEquals(1, multiItem.get(0)); + multiItem.addFront(30); + assertEquals(30, multiItem.get(0)); } @Test void addBack() { + assertEquals(0, emptyList.size()); + emptyList.addBack(27); + assertEquals(27, emptyList.get(emptyList.size() - 1)); + + assertEquals(1, singleItem.get(0)); + singleItem.addBack(21); + assertEquals(21, singleItem.get(singleItem.size() - 1)); + + assertEquals(10, multiItem.get(multiItem.size() - 1)); + multiItem.addBack(30); + assertEquals(30, multiItem.get(multiItem.size() - 1)); } @Test void add() { + assertEquals(0, emptyList.size()); + emptyList.add(0, 27); + assertEquals(27, emptyList.get(0)); + + assertEquals(1, singleItem.get(0)); + singleItem.add(0, 21); + assertEquals(21, singleItem.get(0)); + + assertEquals(10, multiItem.get(multiItem.size() - 1)); + multiItem.add(7,30); + assertEquals(30, multiItem.get(7)); } @Test void get() { + assertEquals(1, singleItem.get(0)); + + assertEquals(5, multiItem.get(4)); } @Test void set() { + assertEquals(1, singleItem.get(0)); + singleItem.set(0, 20); + assertEquals(20, singleItem.get(0)); + + assertEquals(5, multiItem.get(4)); + multiItem.set(4, 67); + assertEquals(67, multiItem.get(4)); } @Test void removeFront() { + assertEquals(1, singleItem.get(0)); + assertEquals(1, singleItem.size()); + assertEquals(1, singleItem.removeFront()); + assertEquals(0, singleItem.size()); + + assertEquals(1, multiItem.get(0)); + assertEquals(10, multiItem.size()); + assertEquals(1, multiItem.removeFront()); + assertEquals(9, multiItem.size()); + } @Test void removeBack() { + assertEquals(1, singleItem.get(0)); + assertEquals(1, singleItem.removeBack()); + + assertEquals(10, multiItem.get(multiItem.size() - 1)); + assertEquals(10, multiItem.removeBack()); } @Test - void remove() { + void removeItem() { + Integer val = new Integer(1); + Integer val2 = new Integer(7); + + assertTrue(singleItem.contains(1)); + singleItem.remove(val); + assertEquals(0, singleItem.size()); + assertFalse(singleItem.contains(1)); + + assertTrue(multiItem.contains(7)); + multiItem.remove(val2); + assertFalse(multiItem.contains(7)); } @Test - void testRemove() { + void removeIndex() { + assertTrue(singleItem.contains(1)); + singleItem.remove(0); + assertEquals(0, singleItem.size()); + assertFalse(singleItem.contains(1)); + + assertTrue(multiItem.contains(7)); + multiItem.remove(6); + assertFalse(multiItem.contains(7)); } @Test void contains() { + assertFalse(emptyList.contains(20)); + assertTrue(singleItem.contains(1)); + assertTrue(multiItem.contains(7)); } @Test void isEmpty() { + assertTrue(emptyList.isEmpty()); + assertFalse(singleItem.isEmpty()); + assertFalse(multiItem.isEmpty()); } @Test void size() { - } - - @Test - void iterator() { + assertEquals(0, emptyList.size()); + assertEquals(1, singleItem.size()); + assertEquals(10, multiItem.size()); } } \ No newline at end of file From fe8306dcc7034f79fe84130dcb57ea2e08eaf9a9 Mon Sep 17 00:00:00 2001 From: Gecervantes01 Date: Sun, 11 Feb 2024 14:32:58 -0800 Subject: [PATCH 5/7] Added runtime analysis to all methods in ArrayList.java --- src/ArrayList.java | 44 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 39 insertions(+), 5 deletions(-) diff --git a/src/ArrayList.java b/src/ArrayList.java index ab6a8b7..6320fff 100644 --- a/src/ArrayList.java +++ b/src/ArrayList.java @@ -14,7 +14,8 @@ public ArrayList() { /** * Add item to the front. * - * Runtime analysis: O(N) + * Runtime analysis: Best case is O(1) constant for an empty array, and worse case is O(N) + * for looping through an entire array shifting all values over. * * @param item the item to be added */ @@ -33,6 +34,9 @@ public void addFront(E item) { /** * Add item to the back. * + * Runtime Analysis: Best case is O(1) for an empty array/ array that's + * not full. Worst case is O(N) linear having to increase the buffer size. + * * @param item the item to be added */ @Override @@ -47,6 +51,9 @@ public void addBack(E item) { /** * Add an item at specified index (position). * + * Runtime Analysis: Best case is O(1) for an empty array, adding a value at index 0. Worst case is + * O(N) for looping through an entire array of N size, or if the length needs to be increased. + * * @param i the index where the item should be added * @param item the item to be added */ @@ -75,6 +82,9 @@ public void add(int i, E item) { /** * Get the item at a specified index. * + * Runtime Analysis: Worst case is O(1) for an empty array, and returning + * a value at a specified index. + * * @param i the index where the item should be retrieved * @return the item located at that index */ @@ -93,6 +103,9 @@ public E get(int i) { * Set (save) an item at a specified index. Previous * item at that index is overwritten. * + * Runtime Analysis: Best case is O(1) for an empty array, and only having to access + * an index/ change the value. + * * @param i the index where the item should be saved * @param item the item to be saved */ @@ -115,6 +128,9 @@ public void set(int i, E item) { /** * Remove item at the front of the list. * + * Runtime Analysis: Best case is O(1) for an empty array, and worst case is + * O(N) for looping through an entire array to shift all values over. + * * @return the item that was removed */ @Override @@ -134,6 +150,9 @@ public E removeFront() { /** * Remove item at the back of the list * + * Runtime Analysis: Best case is O(1) for an empty array, and worst case is + * O(N) for looping through an entire array of N size. + * * @return the item that was removed */ @Override @@ -151,6 +170,9 @@ public E removeBack() { /** * Remove item from the list * + * Runtime Analysis: Best case is O(1) constant for an empty array. Worst case is + * O(N) linear with having to loop through an array then calling the remove method. + * * @param item the item to be removed */ @Override @@ -170,6 +192,10 @@ public void remove(E item) { /** * Remove item at a specified index. * + * Runtime Analysis: Best case is O(1) constant in the case of an empty + * array/invalid index. At its worst it's O(N) linear due to looping through an array + * of N size, and the index potentially being at the end. + * * @param i the index where the item should be removed * @return the item that was removed */ @@ -190,7 +216,10 @@ public E remove(int i) { /** * Checks if an item is in the list. * - * Runtime Analysis: O(N) Linear + * Runtime Analysis: At its best the method runs at O(1) in the case of + * an empty array, and at its worst O(N) Linear due looping through an + * array of N length with the possibility of the desired val being at + * the end. * * @param item the item to search for * @return true if the item is in the list, false otherwise @@ -211,7 +240,9 @@ public boolean contains(E item) { /** * Checks if the list is empty. * - * Runtime Analysis: O(1) constant + * Runtime Analysis: O(1) constant, this is the worst + * case scenario because it simply returns the result of + * a comparison. * * @return true if the list is empty, false otherwise */ @@ -223,7 +254,8 @@ public boolean isEmpty() { /** * Provides a count of the number of items in the list. * - * Runtime Analysis: O(1) constant + * Runtime Analysis: Runs at O(1) constant at it's worst + * because it's always just returning a single variable. * * @return number of items in the list */ @@ -234,7 +266,9 @@ public int size() { /** - * Runtime analysis: At it's worst it's O(N) linear. + * Runtime analysis: At it's worst it's O(N) linear because it has + * to loop through all values an array twice, and the size of the + * array can vary. */ private void increaseBuffer() { From c0ad10c7e7771698ba385104f2f3358b130ed2e2 Mon Sep 17 00:00:00 2001 From: Gecervantes01 Date: Sun, 11 Feb 2024 14:54:04 -0800 Subject: [PATCH 6/7] Added runtime analysis to all methods in LinkedList.java --- src/LinkedList.java | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/src/LinkedList.java b/src/LinkedList.java index b043f41..b23a1e8 100644 --- a/src/LinkedList.java +++ b/src/LinkedList.java @@ -19,6 +19,9 @@ public LinkedList() { /** * Add item to the front. * + * Runtime Analysis: This method runs at O(1) constant for either an empty list + * or just adding node to the front. + * * @param item the item to be added */ @Override @@ -33,6 +36,9 @@ public void addFront(E item) { /** * Add item to the back. * + * Runtime Analysis: At its best this method runs at O(1) constant for an empty list, + * at its worst is O(N) linear having to loop through the entire list with N size. + * * @param item the item to be added */ @Override @@ -59,6 +65,10 @@ public void addBack(E item) { /** * Add an item at specified index (position). * + * Runtime Analysis: At its best this method runs at O(1) constant for an empty list or with + * the index being 0. At its worst is O(N) linear having to loop through the entire list with N size + * to reach the last node. + * * @param i the index where the item should be added * @param item the item to be added */ @@ -87,6 +97,10 @@ public void add(int i, E item) { /** * Get the item at a specified index. * + * Runtime Analysis: This method runs at O(1) constant at its best for an + * empty list/ desired index being the front. At its worst it runs at + * O(N) if the desired value is at the end of the list. + * * @param i the index where the item should be retrieved * @return the item located at that index */ @@ -114,6 +128,10 @@ public E get(int i) { * Set (save) an item at a specified index. Previous * item at that index is overwritten. * + * Runtime Analysis: At its best this method runs at O(1) constant for an empty list + * or desired node to be changed at the front. At its worst is O(N) linear having to loop + * through the entire list with N size to set the last node. + * * @param i the index where the item should be saved * @param item the item to be saved */ @@ -136,6 +154,9 @@ public void set(int i, E item) { /** * Remove item at the front of the list. * + * Runtime Analysis: This method runs at O(1) constant for an empty list, and for + * removing the first node. + * * @return the item that was removed */ @Override @@ -152,6 +173,10 @@ public E removeFront() { /** * Remove item at the back of the list * + * Runtime Analysis: At its best this method runs at O(1) constant for an empty list, + * or a list of size 1. At its worst is O(N) linear having to loop through the entire + * list with N size. + * * @return the item that was removed */ @Override @@ -177,6 +202,10 @@ public E removeBack() { /** * Remove item from the list * + * Runtime Analysis: At its best this method runs at O(1) constant for an empty list/ single value + * list. At its worst is O(N) linear having to loop through the entire list with N size to check + * for desired value. + * * @param item the item to be removed */ @Override @@ -201,6 +230,10 @@ public void remove(E item) { /** * Remove item at a specified index. * + * Runtime Analysis: At its best this method runs at O(1) constant for an empty list or index + * being 0. At its worst is O(N) linear having to loop through the entire list with N size to + * reach last index. + * * @param i the index where the item should be removed * @return the item that was removed */ @@ -234,6 +267,10 @@ public E remove(int i) { /** * Checks if an item is in the list. * + * Runtime Analysis: This method runs at O(N) linear due to + * having to loop through the entire array to check for the + * val. + * * @param item the item to search for * @return true if the item is in the list, false otherwise */ @@ -255,6 +292,9 @@ public boolean contains(E item) { /** * Checks if the list is empty. * + * Runtime Analysis: This method runs at O(1) constant always returning + * the result of a check. + * * @return true if the list is empty, false otherwise */ @Override @@ -265,6 +305,8 @@ public boolean isEmpty() { /** * Provides a count of the number of items in the list. * + * Runtime Analysis: This method runs at O(1) constant always returning size. + * * @return number of items in the list */ @Override From 7545cd1e03618cde40eb24cc422896979214a85b Mon Sep 17 00:00:00 2001 From: Gecervantes01 Date: Mon, 12 Feb 2024 20:39:23 -0800 Subject: [PATCH 7/7] Created and finished the Bag API, ResizingArrayStack.java class and the test client. --- src/Bag.java | 30 +++++++++ src/ResizingArrayStack.java | 117 ++++++++++++++++++++++++++++++++++++ src/StackTestClient.java | 20 ++++++ 3 files changed, 167 insertions(+) create mode 100644 src/Bag.java create mode 100644 src/ResizingArrayStack.java create mode 100644 src/StackTestClient.java diff --git a/src/Bag.java b/src/Bag.java new file mode 100644 index 0000000..c7b844c --- /dev/null +++ b/src/Bag.java @@ -0,0 +1,30 @@ +/** + * Bag API + * + * @param class / datatype of items in the Bag. + */ +public interface Bag extends Iterable { + + /** + * Adds an item to the bag. + * + * @param item the item to be added + */ + void add(E item); + + /** + * Checks if the Bag is empty. + * + * @return true if the bag is empty, otherwise returns false. + */ + boolean isEmpty(); + + /** + * Keeps track of the current number of items stored within + * the bag. Increments and decreases any time a value is + * added/removed. + * + * @return current size of the bag. + */ + int size(); +} diff --git a/src/ResizingArrayStack.java b/src/ResizingArrayStack.java new file mode 100644 index 0000000..e89a38e --- /dev/null +++ b/src/ResizingArrayStack.java @@ -0,0 +1,117 @@ +import java.util.Iterator; +import java.util.NoSuchElementException; + +public class ResizingArrayStack implements Stack { + + private E[] buffer; + private int size; + + public ResizingArrayStack() { + buffer = (E[]) new Object[50]; + size = 0; + } + + /** + * Add an item to the stack. + * + * @param item the item to be added + */ + @Override + public void push(E item) { + if(size == buffer.length) { + increaseBuffer(buffer.length * 2); + } + buffer[size] = item; + size++; + } + + /** + * Removes the most recently added item from the stack. + * + * @return the item that was removed + */ + @Override + public E pop() { + E removedItem = buffer[size - 1]; + buffer[size - 1] = null; + size--; + if(size > 0 && size == buffer.length/4) { + increaseBuffer(buffer.length / 2); + } + return removedItem; + } + + /** + * Returns the item at the top of the stack. + * Does not modify the stack or the item at the top. + * + * @return item at the top of the stack. + */ + @Override + public E peek() { + if(isEmpty()) { + throw new NoSuchElementException("Stack is empty, no value to return"); + } + return buffer[size - 1]; + } + + /** + * Checks to see if the stack is empty. + * + * @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. + * + * @return the number of items in the stack + */ + @Override + public int size() { + return size; + } + + private void increaseBuffer(int max) { + E[] temp = (E[]) new Object[max]; + for(int i = 0; i < size; i++) { + temp[i] = buffer[i]; + } + buffer = temp; + } + + /** + * Returns an iterator over elements of type {@code T}. + * + * @return an Iterator. + */ + @Override + public Iterator iterator() { + return new ResizingArrayStackIterator(); + } + + private class ResizingArrayStackIterator implements Iterator { + private int i; + + private ResizingArrayStackIterator() { + i = size; + } + + public boolean hasNext() { + return i > 0; + } + + public E next() { + if(!hasNext()) { + throw new NoSuchElementException(); + } + E currentVal = buffer[i]; + i--; + return currentVal; + } + + } +} diff --git a/src/StackTestClient.java b/src/StackTestClient.java new file mode 100644 index 0000000..001789c --- /dev/null +++ b/src/StackTestClient.java @@ -0,0 +1,20 @@ +import java.util.Scanner; + 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"); + } +}