From 7d77364b0693b1a42f40da0240ae3c452cb7092f Mon Sep 17 00:00:00 2001 From: tobygoetz Date: Thu, 8 Feb 2024 20:25:22 -0800 Subject: [PATCH 01/10] Reorganized Project Directory, implemented addFront(), addBack(), add(), get(), set(), removeFront(), resize(), toString(), and iterator(). --- .idea/inspectionProfiles/Project_Default.xml | 299 ++++++++++++++++++ .idea/uiDesigner.xml | 124 ++++++++ .idea/vcs.xml | 6 + src/Main.java | 10 - src/abstractDataTypes/ArrayList.java | 306 +++++++++++++++++++ src/driver/Main.java | 105 +++++++ src/{ => interfaces}/Deque.java | 4 +- src/{ => interfaces}/List.java | 4 +- src/{ => interfaces}/MathSet.java | 16 +- src/{ => interfaces}/Queue.java | 4 +- src/{ => interfaces}/Stack.java | 4 +- 11 files changed, 861 insertions(+), 21 deletions(-) create mode 100644 .idea/inspectionProfiles/Project_Default.xml create mode 100644 .idea/uiDesigner.xml create mode 100644 .idea/vcs.xml delete mode 100644 src/Main.java create mode 100644 src/abstractDataTypes/ArrayList.java create mode 100644 src/driver/Main.java rename src/{ => interfaces}/Deque.java (92%) rename src/{ => interfaces}/List.java (96%) rename src/{ => interfaces}/MathSet.java (85%) rename src/{ => interfaces}/Queue.java (89%) rename src/{ => interfaces}/Stack.java (91%) diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..9c7d568 --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,299 @@ + + + + \ No newline at end of file diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml new file mode 100644 index 0000000..2b63946 --- /dev/null +++ b/.idea/uiDesigner.xml @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file 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/Main.java b/src/Main.java deleted file mode 100644 index 8f8f984..0000000 --- a/src/Main.java +++ /dev/null @@ -1,10 +0,0 @@ -//TIP To Run code, press or -// click the icon in the gutter. -public class Main { - public static void main(String[] args) { - //TIP Press with your caret at the highlighted text - // to see how IntelliJ IDEA suggests fixing it. - System.out.println("Hello and welcome!"); - - } -} \ No newline at end of file diff --git a/src/abstractDataTypes/ArrayList.java b/src/abstractDataTypes/ArrayList.java new file mode 100644 index 0000000..6b7be74 --- /dev/null +++ b/src/abstractDataTypes/ArrayList.java @@ -0,0 +1,306 @@ +package abstractDataTypes; + +import interfaces.List; + +import java.util.Arrays; +import java.util.Iterator; +import java.util.NoSuchElementException; + +/** + * @author tobygoetz + * @version 1.0 + * Generic ArrayList, to be used with any data type + * @param specifies data type to be used in ArrayList + */ +public class ArrayList implements List { + + private static final int CAPACITY = 10; + + // fields + private E[] buffer; + private int size; + + /** + * Constructor for ArrayList + */ + public ArrayList() + { + size = 0; + buffer = (E[]) new Object[CAPACITY]; + } + + + /** + * Add item to the front. + * + * @param item the item to be added + */ + @Override + public void addFront(Object item) + { + //loop while index is greater than zero + for (int i = size; i > 0; i--) { + //if buffer is at capacity increase buffer by one index + if (size == buffer.length) { + this.resize(); + } + //index at highest buffer gets shifted right + buffer[i] = buffer[i - 1]; + } + buffer[0] = (E) item; + size++; + } + + /** + * Add item to the back. + * + * @param item the item to be added + */ + @Override + public void addBack(E item) + { + //if buffer is at capacity increase buffer by one index + if ( size == buffer.length) { + resize(); + } + //add value to size which is one index greater than last value + buffer[size] = item; + size++; + } + + /** + * Add an item at specified index (position). + * + * @param index the index where the item should be added + * @param item the item to be added + */ + @Override + public void add(int index, E item) + { + if (index < 0 || index > size) { + throw new IndexOutOfBoundsException("Specified Index Must Be " + + "In the Range of 0-" + size); + } else { + //loop while index is greater than index value specified + for (int i = size; i >= index; i--) { + //if buffer is at capacity increase buffer by one index + if (size == buffer.length) { + this.resize(); + } + //index at highest buffer gets shifted right + if (i != 0) { + buffer[i] = buffer[i - 1]; + } + } + } + buffer[index] = item; + size++; + } + + /** + * Get the item at a specified index. + * + * @param index the index where the item should be retrieved + * @return the item located at that index + */ + @Override + public E get(int index) + { + if (index < 0 ) { + throw new IndexOutOfBoundsException( + "Index must be greater than 0"); + } else if (index >= size ) { + if (size == 0) { + throw new IndexOutOfBoundsException( + "This list is empty"); + } else { + throw new IndexOutOfBoundsException( + "Specified Index Must Be " + + "In the Range of 0-" + (size - 1)); + } + } return buffer[index]; + } + + /** + * Set (save) an item at a specified index. Previous + * item at that index is overwritten. + * + * @param index the index where the item should be saved + * @param item the item to be saved + */ + @Override + public void set(int index, E item) + { + if (index < 0 || index >= size) { + throw new IndexOutOfBoundsException("Specified Index Must Be " + + "In the Range of 0-" + (size - 1)); + } else { + buffer[index] = item; + } + } + + /** + * Remove item at the front of the list. + * + * @return the item that was removed + */ + @Override + public E removeFront() + { + if (!isEmpty()) { + E removed = buffer[0]; + for (int i = 0; i <= size - 1; i++) { + buffer[i] = buffer[i + 1]; + } + size--; + return removed; + } else { + 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(Object item) { + + } + + /** + * Remove item at a specified index. + * + * @param index the index where the item should be removed + * @return the item that was removed + */ + @Override + public E remove(int index) { + 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(Object item) { + return false; + } + + /** + * Checks if the list is empty. + * + * @return true if the list is empty, false otherwise + */ + @Override + public boolean isEmpty() { + return size == 0 && buffer[0] == null; + } + + /** + * 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 ArrayListIterator(); + } + + private class ArrayListIterator implements Iterator { + + private int index; + + private ArrayListIterator() { index = 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 index < 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 (index >= size) { + throw new NoSuchElementException("Index is out of range"); + } + + E currentValue = buffer[index]; + index++; + return currentValue; + } + } + + /** + * Helper method to resize ArrayIntlist to support + * more data + */ + private void resize() { + //create new space, separate from the old space (buffer) + int newSize = size + CAPACITY; + E[] newBuffer = (E[]) new Object[newSize]; + + // copy everything over from buffer into newBuffer + if (newSize > buffer.length) { + for (int i = 0; i < buffer.length; i++) { + newBuffer[i] = buffer[i]; + } + } else { + for (int i = 0; i < newBuffer.length; i++) { + newBuffer[i] = buffer[i]; + } + } + + // set the new space into buffer + buffer = newBuffer; + + // the old space is no longer "pointed to" and will eventually + // be cleaned up by the garbage collector + } + + + @Override + public String toString() { + return "ArrayList{" + + "size=" + size + + ", indices=" + Arrays.toString(buffer) + + + '}'; + } +} diff --git a/src/driver/Main.java b/src/driver/Main.java new file mode 100644 index 0000000..78b112f --- /dev/null +++ b/src/driver/Main.java @@ -0,0 +1,105 @@ +package driver; + +import abstractDataTypes.ArrayList; + +import java.awt.*; + +//TIP To Run code, press or +// click the icon in the gutter. +public class Main { + + public static final int ITERATIONS = 25; + public static void main(String[] args) { + //TIP Press with your caret at the highlighted text + // to see how IntelliJ IDEA suggests fixing it. + System.out.println("Hello and welcome!"); + + class Cat { + String breed; + + public Cat(String breed) { + this.breed = breed; + } + + @Override + public String toString() { + return breed; + } + } + + String[] breeds = new String[]{ + "Tabby", "Siamese", "Calico", + "Tabby", "Siamese", "Calico", + "Tabby", "Siamese", "Calico", + "Tabby", "Siamese", "Calico", + "Tabby", "Siamese", "Calico", + "Tabby", "Siamese", "Calico", + "Tabby", "Siamese", "Calico", + "Tabby", "Siamese", "Calico", + "Tabby", "Siamese", "Calico",}; + + Cat[] cats = new Cat[ITERATIONS]; + for (int i = 0; i < ITERATIONS; i++) { + cats[i] = new Cat(breeds[i]); +// System.out.println(cats[i]); + + } + + ArrayList list = new ArrayList<>(); + testArrayList(list); + + ArrayList listOfObjects = new ArrayList<>(); + listOfObjects.addFront(10); + listOfObjects.addFront("Fresno"); + listOfObjects.addFront(1.55555555); + listOfObjects.addFront('a'); + listOfObjects.addFront(new Cat(breeds[1])); + listOfObjects.addFront(breeds.toString()); + + System.out.println(listOfObjects); + listOfObjects.addBack(new Cat(breeds[0])); + listOfObjects.addBack(new Cat(breeds[0])); + listOfObjects.addBack(new Cat(breeds[0])); + listOfObjects.addBack(new Cat(breeds[0])); + listOfObjects.addBack(new Cat(breeds[0])); + listOfObjects.addBack(new Cat(breeds[0])); + System.out.println(listOfObjects); + + listOfObjects.set(0, 0); + listOfObjects.set((listOfObjects.size() -1), (listOfObjects.size() - 1)); + + + System.out.println(listOfObjects.size()); + + + System.out.println(listOfObjects); + + System.out.println(listOfObjects.removeFront()); + + System.out.println(listOfObjects); + + + while (!listOfObjects.isEmpty()) { + System.out.println(listOfObjects.removeFront()); + System.out.println(listOfObjects); + } + + System.out.println(listOfObjects.removeFront()); + System.out.println(listOfObjects); + + + + } + + public static void testArrayList(ArrayList list) { + + for (int i = 0; i < ITERATIONS; i++) { + list.addFront(i); + + } + + System.out.println(list); + + + } +} \ No newline at end of file diff --git a/src/Deque.java b/src/interfaces/Deque.java similarity index 92% rename from src/Deque.java rename to src/interfaces/Deque.java index 0107f47..ccc0916 100644 --- a/src/Deque.java +++ b/src/interfaces/Deque.java @@ -1,5 +1,7 @@ +package interfaces; + /** - * Deque: double-ended queue API + * interfaces.Deque: double-ended queue API * Supports adding and removing items at both ends. * * @param diff --git a/src/List.java b/src/interfaces/List.java similarity index 96% rename from src/List.java rename to src/interfaces/List.java index 2bf4aef..384b294 100644 --- a/src/List.java +++ b/src/interfaces/List.java @@ -1,5 +1,7 @@ +package interfaces; + /*** - * List interface (API / abstract data type) + * interfaces.List interface (API / abstract data type) * @param Class or data type of the items in the list. */ public interface List extends Iterable { diff --git a/src/MathSet.java b/src/interfaces/MathSet.java similarity index 85% rename from src/MathSet.java rename to src/interfaces/MathSet.java index 5464cf7..b8ca20d 100644 --- a/src/MathSet.java +++ b/src/interfaces/MathSet.java @@ -1,12 +1,14 @@ +package interfaces; + /** - * MathSet API (interface / abstract data type) + * interfaces.MathSet API (interface / abstract data type) * represents a mathematical set. Sets in mathematics * have unique elements (keys) and there are no duplicate keys. * - * In this MathSet API, we have an additional constraint that + * In this interfaces.MathSet API, we have an additional constraint that * traditional mathematical sets do not have. In mathematical sets, * elements are unordered, order of keys does not matter. In this - * MathSet API, we require items to be Comparable so we can maintain + * interfaces.MathSet API, we require items to be Comparable so we can maintain * them in order. By keeping items in order, we can guarantee * some reasonable performance for the set operations (union, * intersection, difference, symmetric difference) and for search @@ -60,7 +62,7 @@ public interface MathSet extends Iterable { * Computes the union of this set and another specified set. * Does not change the contents of this set. * @param other the second set for the operation - * @return new MathSet that contains the union + * @return new interfaces.MathSet that contains the union */ MathSet union(MathSet other); @@ -68,7 +70,7 @@ public interface MathSet extends Iterable { * Computes the intersection of this set and another specified set. * Does not change the contents of this set. * @param other the second set for the operation - * @return new MathSet that contains the intersection + * @return new interfaces.MathSet that contains the intersection */ MathSet intersection(MathSet other); @@ -76,7 +78,7 @@ public interface MathSet extends Iterable { * Computes the difference of this set and another specified set. * Does not change the contents of this set. * @param other the second set for the operation - * @return new MathSet that contains the difference + * @return new interfaces.MathSet that contains the difference */ MathSet difference(MathSet other); @@ -84,7 +86,7 @@ public interface MathSet extends Iterable { * Computes the symmetric difference of this set and another specified set. * Does not change the contents of this set. * @param other the second set for the operation - * @return new MathSet that contains the symmetric difference + * @return new interfaces.MathSet that contains the symmetric difference */ MathSet symmetricDifference(MathSet other); diff --git a/src/Queue.java b/src/interfaces/Queue.java similarity index 89% rename from src/Queue.java rename to src/interfaces/Queue.java index ab5ca29..bceaf58 100644 --- a/src/Queue.java +++ b/src/interfaces/Queue.java @@ -1,5 +1,7 @@ +package interfaces; + /** - * FIFO (first-in, first-out) Queue API + * FIFO (first-in, first-out) interfaces.Queue API * @param class / data type of the items in the queue */ public interface Queue extends Iterable { diff --git a/src/Stack.java b/src/interfaces/Stack.java similarity index 91% rename from src/Stack.java rename to src/interfaces/Stack.java index bb1000d..f6ddac7 100644 --- a/src/Stack.java +++ b/src/interfaces/Stack.java @@ -1,5 +1,7 @@ +package interfaces; + /** - * Stack (LIFO: last-in, first-out) API + * interfaces.Stack (LIFO: last-in, first-out) API * @param class / data type of the items in the stack */ public interface Stack extends Iterable { From dc3ba629a024e9156d136ae1ad6a6f5c52e6d639 Mon Sep 17 00:00:00 2001 From: tobygoetz Date: Sun, 11 Feb 2024 20:22:15 -0800 Subject: [PATCH 02/10] Updated resize() to resize array everytime a single element is added (my thought is that the garbage collector will take care of it, instead of storing an array with a potentially large around of indices that are null). Implemented removeFront(), removeBack(), remove(E item), remove(int index) and contains(). --- src/abstractDataTypes/ArrayList.java | 98 +++++++++++++++++++++++----- src/driver/Main.java | 52 +++++++++++---- 2 files changed, 122 insertions(+), 28 deletions(-) diff --git a/src/abstractDataTypes/ArrayList.java b/src/abstractDataTypes/ArrayList.java index 6b7be74..22d0f01 100644 --- a/src/abstractDataTypes/ArrayList.java +++ b/src/abstractDataTypes/ArrayList.java @@ -42,7 +42,7 @@ public void addFront(Object item) for (int i = size; i > 0; i--) { //if buffer is at capacity increase buffer by one index if (size == buffer.length) { - this.resize(); + this.resize(buffer.length + 1); } //index at highest buffer gets shifted right buffer[i] = buffer[i - 1]; @@ -61,7 +61,7 @@ public void addBack(E item) { //if buffer is at capacity increase buffer by one index if ( size == buffer.length) { - resize(); + resize(size + 1); } //add value to size which is one index greater than last value buffer[size] = item; @@ -85,7 +85,7 @@ public void add(int index, E item) for (int i = size; i >= index; i--) { //if buffer is at capacity increase buffer by one index if (size == buffer.length) { - this.resize(); + this.resize(buffer.length + 1); } //index at highest buffer gets shifted right if (i != 0) { @@ -149,10 +149,17 @@ public E removeFront() { if (!isEmpty()) { E removed = buffer[0]; - for (int i = 0; i <= size - 1; i++) { + for (int i = 0; i <= size - 2; i++) { buffer[i] = buffer[i + 1]; + } size--; + + //Reduce buffer until original buffer size is reached + if (size >= 10) { + resize(size); + //after buffer becomes 10 set removed values back to null + } else { + buffer[size] = null; } - size--; return removed; } else { return null; @@ -165,8 +172,16 @@ public E removeFront() * @return the item that was removed */ @Override - public E removeBack() { - return null; + public E removeBack() + { + if (!isEmpty()) { + E removed = buffer[size - 1]; + buffer[size - 1] = null; + size--; + return removed; + } else { + return null; + } } /** @@ -175,8 +190,30 @@ public E removeBack() { * @param item the item to be removed */ @Override - public void remove(Object item) { - + public void remove(E item) + { + if (this.contains(item)) { + if (this.buffer[0].equals(item)) { + this.removeFront(); + } else if (this.buffer[size - 1].equals(item)) { + this.removeBack(); + } else { + int index = 0; + while (!buffer[index].equals(item)) { + index++; + } + for (int i = index; i < size - 1; i++) { + buffer[i] = buffer[i + 1]; + } + size--; + if (size >= 10) { + resize(size); + //after buffer becomes 10 set removed values back to null + } else { + buffer[size] = null; + } + } + } } /** @@ -186,8 +223,31 @@ public void remove(Object item) { * @return the item that was removed */ @Override - public E remove(int index) { - return null; + public E remove(int index) + { + // first, check the index to see if it is valid + if (index < 0) { + throw new IndexOutOfBoundsException("Index cannot be negative"); + } else if (index >= size) { + throw new IndexOutOfBoundsException("Index is higher than size"); + } + + // save a copy of the value to be removed so that we can return it later + E copyOfRemovedValue = buffer[index]; + + // if index is last index with valid data, set data to null + if (index == size - 1) { + buffer[index] = null; + // shift all values over starting at index to be removed + } else { + for (int i = index; i < size - 1; i++) { + buffer[i] = buffer[i + 1]; + } + } size--; + // set trailing index to null to account for reduced size + buffer[size] = null; + + return copyOfRemovedValue; } /** @@ -197,8 +257,16 @@ public E remove(int index) { * @return true if the item is in the list, false otherwise */ @Override - public boolean contains(Object item) { - return false; + public boolean contains(Object item) + { + int index = 0; + while (index != size) { + if (buffer[index].equals(item)) { + return true; + } else { + index++; + } + } return false; } /** @@ -271,9 +339,9 @@ public E next() { * Helper method to resize ArrayIntlist to support * more data */ - private void resize() { + private void resize(int newSize) { //create new space, separate from the old space (buffer) - int newSize = size + CAPACITY; +// int newSize = size + CAPACITY; E[] newBuffer = (E[]) new Object[newSize]; // copy everything over from buffer into newBuffer diff --git a/src/driver/Main.java b/src/driver/Main.java index 78b112f..d2e47e1 100644 --- a/src/driver/Main.java +++ b/src/driver/Main.java @@ -46,7 +46,7 @@ public String toString() { } ArrayList list = new ArrayList<>(); - testArrayList(list); +// testArrayList(list); ArrayList listOfObjects = new ArrayList<>(); listOfObjects.addFront(10); @@ -54,38 +54,64 @@ public String toString() { listOfObjects.addFront(1.55555555); listOfObjects.addFront('a'); listOfObjects.addFront(new Cat(breeds[1])); - listOfObjects.addFront(breeds.toString()); + listOfObjects.addFront(breeds); System.out.println(listOfObjects); + listOfObjects.addBack(new Cat(breeds[0])); - listOfObjects.addBack(new Cat(breeds[0])); + listOfObjects.addBack(new Cat(breeds[1])); listOfObjects.addBack(new Cat(breeds[0])); listOfObjects.addBack(new Cat(breeds[0])); listOfObjects.addBack(new Cat(breeds[0])); listOfObjects.addBack(new Cat(breeds[0])); System.out.println(listOfObjects); - +// listOfObjects.set(0, 0); - listOfObjects.set((listOfObjects.size() -1), (listOfObjects.size() - 1)); + System.out.println(listOfObjects); + listOfObjects.set((listOfObjects.size() -1), (listOfObjects.size() - 1)); + listOfObjects.set(0, "front"); System.out.println(listOfObjects.size()); - - System.out.println(listOfObjects); System.out.println(listOfObjects.removeFront()); - + System.out.println(listOfObjects.removeFront()); + System.out.println(listOfObjects.removeBack()); + System.out.println(listOfObjects.removeBack()); + Cat lion = new Cat("Lion"); + listOfObjects.addFront(lion); + + System.out.println(listOfObjects.contains(lion)); + listOfObjects.removeBack(); + listOfObjects.removeBack(); + listOfObjects.removeBack(); + listOfObjects.removeBack(); + listOfObjects.removeBack(); + System.out.println(listOfObjects.contains("Fresn!")); + System.out.println(listOfObjects); + System.out.println(listOfObjects.contains('a')); - while (!listOfObjects.isEmpty()) { - System.out.println(listOfObjects.removeFront()); - System.out.println(listOfObjects); - } - System.out.println(listOfObjects.removeFront()); + + + System.out.println(); System.out.println(listOfObjects); + listOfObjects.remove((Object) "Fresno"); + System.out.println(listOfObjects); + + + + +// while (!listOfObjects.isEmpty()) { +// System.out.println(listOfObjects.removeFront()); +// System.out.println(listOfObjects); +// } +// +// System.out.println(listOfObjects.removeFront()); +// System.out.println(listOfObjects); From 3db228f584758ee060a39cc45739c0df2877ed2b Mon Sep 17 00:00:00 2001 From: tobygoetz Date: Sun, 11 Feb 2024 20:38:06 -0800 Subject: [PATCH 03/10] Updated resize() to resize array everytime a single element is added (my thought is that the garbage collector will take care of it, instead of storing an array with a potentially large around of indices that are null). Implemented removeFront(), removeBack(), remove(E item), remove(int index) and contains(). --- src/driver/Main.java | 73 +++++++++++----------------------------- src/interfaces/List.java | 20 ++++++----- 2 files changed, 30 insertions(+), 63 deletions(-) diff --git a/src/driver/Main.java b/src/driver/Main.java index d2e47e1..9ab4bf6 100644 --- a/src/driver/Main.java +++ b/src/driver/Main.java @@ -2,20 +2,30 @@ import abstractDataTypes.ArrayList; -import java.awt.*; - //TIP To Run code, press or // click the icon in the gutter. + +/** + * @author tobygoetz + * @version 1.0 + * Driver class to test ArrayList and LinkedList that + * implement list.java + */ public class Main { public static final int ITERATIONS = 25; + + /** + * program to run Main Class + * @param args command line arguments + */ public static void main(String[] args) { //TIP Press with your caret at the highlighted text // to see how IntelliJ IDEA suggests fixing it. System.out.println("Hello and welcome!"); class Cat { - String breed; + private String breed; public Cat(String breed) { this.breed = breed; @@ -28,30 +38,12 @@ public String toString() { } String[] breeds = new String[]{ - "Tabby", "Siamese", "Calico", - "Tabby", "Siamese", "Calico", - "Tabby", "Siamese", "Calico", - "Tabby", "Siamese", "Calico", - "Tabby", "Siamese", "Calico", - "Tabby", "Siamese", "Calico", - "Tabby", "Siamese", "Calico", - "Tabby", "Siamese", "Calico", - "Tabby", "Siamese", "Calico",}; - - Cat[] cats = new Cat[ITERATIONS]; - for (int i = 0; i < ITERATIONS; i++) { - cats[i] = new Cat(breeds[i]); -// System.out.println(cats[i]); - - } - - ArrayList list = new ArrayList<>(); -// testArrayList(list); + "Tabby", "Siamese", "Calico"}; ArrayList listOfObjects = new ArrayList<>(); listOfObjects.addFront(10); listOfObjects.addFront("Fresno"); - listOfObjects.addFront(1.55555555); + listOfObjects.addFront(ITERATIONS); listOfObjects.addFront('a'); listOfObjects.addFront(new Cat(breeds[1])); listOfObjects.addFront(breeds); @@ -65,11 +57,10 @@ public String toString() { listOfObjects.addBack(new Cat(breeds[0])); listOfObjects.addBack(new Cat(breeds[0])); System.out.println(listOfObjects); -// + listOfObjects.set(0, 0); System.out.println(listOfObjects); - listOfObjects.set((listOfObjects.size() -1), (listOfObjects.size() - 1)); listOfObjects.set(0, "front"); System.out.println(listOfObjects.size()); @@ -94,38 +85,12 @@ public String toString() { System.out.println(listOfObjects.contains('a')); - - - System.out.println(); System.out.println(listOfObjects); - listOfObjects.remove((Object) "Fresno"); + listOfObjects.remove((Object) 'a'); System.out.println(listOfObjects); - - - -// while (!listOfObjects.isEmpty()) { -// System.out.println(listOfObjects.removeFront()); -// System.out.println(listOfObjects); -// } -// -// System.out.println(listOfObjects.removeFront()); -// System.out.println(listOfObjects); - - - - } - - public static void testArrayList(ArrayList list) { - - for (int i = 0; i < ITERATIONS; i++) { - list.addFront(i); - - } - - System.out.println(list); - - + System.out.println(listOfObjects.remove(0)); + System.out.println(listOfObjects); } } \ No newline at end of file diff --git a/src/interfaces/List.java b/src/interfaces/List.java index 384b294..110869a 100644 --- a/src/interfaces/List.java +++ b/src/interfaces/List.java @@ -1,8 +1,10 @@ package interfaces; -/*** +/** * interfaces.List interface (API / abstract data type) * @param Class or data type of the items in the list. + * @author unknown + * @version 1.0 */ public interface List extends Iterable { /** @@ -19,25 +21,25 @@ public interface List extends Iterable { /** * Add an item at specified index (position). - * @param i the index where the item should be added + * @param index the index where the item should be added * @param item the item to be added */ - void add(int i, E item); + void add(int index, E item); /** * Get the item at a specified index. - * @param i the index where the item should be retrieved + * @param index the index where the item should be retrieved * @return the item located at that index */ - E get(int i); + E get(int index); /** * 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 index the index where the item should be saved * @param item the item to be saved */ - void set(int i, E item); + void set(int index, E item); /** * Remove item at the front of the list. @@ -59,10 +61,10 @@ public interface List extends Iterable { /** * Remove item at a specified index. - * @param i the index where the item should be removed + * @param index the index where the item should be removed * @return the item that was removed */ - E remove(int i); + E remove(int index); /** * Checks if an item is in the list. From 9d85255cd8e5701184a1c7b1ca0e54b7e86df453 Mon Sep 17 00:00:00 2001 From: tobygoetz Date: Sun, 11 Feb 2024 23:33:53 -0800 Subject: [PATCH 04/10] Implemented all methods for LinkedList. --- src/abstractDataTypes/ArrayList.java | 2 +- src/abstractDataTypes/LinkedList.java | 427 ++++++++++++++++++++++++++ src/driver/Main.java | 193 ++++++++---- 3 files changed, 559 insertions(+), 63 deletions(-) create mode 100644 src/abstractDataTypes/LinkedList.java diff --git a/src/abstractDataTypes/ArrayList.java b/src/abstractDataTypes/ArrayList.java index 22d0f01..ccbb8af 100644 --- a/src/abstractDataTypes/ArrayList.java +++ b/src/abstractDataTypes/ArrayList.java @@ -36,7 +36,7 @@ public ArrayList() * @param item the item to be added */ @Override - public void addFront(Object item) + public void addFront(E item) { //loop while index is greater than zero for (int i = size; i > 0; i--) { diff --git a/src/abstractDataTypes/LinkedList.java b/src/abstractDataTypes/LinkedList.java new file mode 100644 index 0000000..dddea15 --- /dev/null +++ b/src/abstractDataTypes/LinkedList.java @@ -0,0 +1,427 @@ +package abstractDataTypes; + +import interfaces.List; + +import java.util.Iterator; +import java.util.NoSuchElementException; + +/** + * @author tobygoetz + * @version 1.0 + * + * Generic LinkedList to be used with any data type + * @param + */ +public class LinkedList implements List { + + // Fields + private Node head; + private int size; + + /** + * Constructor to initialize the fields of LinkedIntList + */ + public LinkedList() { + head = null; + size = 0; + } + + // Node Class + private class Node { + private E data; + private Node next; + + /** + * Constuctor for Node that accepts on Integer data + * and sets the next to null + * @param data Integer value of Node + */ + private Node(E data) { + this.data = data; + this.next = null; + } + + /** + * Constuctor for Node that accepts on Integer data + * and sets the next to null + * @param data Integer Value of Node + * @param next Points to the next Node in list + */ + private Node(E data, Node next) { + this.data = data; + this.next = next; + } + + public String toString() { + return data + " -> "; + } + } + + /** + * Add item to the front. + * + * @param item the item to be added + */ + @Override + public void addFront(E item) + { + // new Node to be added + Node addedToFront = new Node(item); + // the list currently has some nodes in it + if (head != null) { + addedToFront.next = head; + } + head = addedToFront; + size++; + } + + /** + * Add item to the back. + * + * @param item the item to be added + */ + @Override + public void addBack(E item) + { + Node addToBack = new Node(item); + + if (head == null) { + head = addToBack; + } else { + Node current = head; + + while (current.next != null) { + current = current.next; + } + current.next = addToBack; + } size++; + } + + /** + * Add an item at specified index (position). + * + * @param index the index where the item should be added + * @param item the item to be added + */ + @Override + public void add(int index, E item) + { + int dex = 1; + //if requested index is out of range throw exception + if (index < 0 || index > (size )) { + throw new IndexOutOfBoundsException( + "Index must be in the Range 0-" + (size)); + //else find Node at index + } else { + //check if index is head + if (index == 0) { + addFront(item); + //check if index is at the end + } else if (index == (size)) { + addBack(item); + //remove everywhere else + } else { + Node current = head; + while (dex <= index - 1) { + current = current.next; + dex++; + } + current.next = new Node(item, current.next); + size++; + } + } + } + + /** + * Get the item at a specified index. + * + * @param index the index where the item should be retrieved + * @return the item located at that index + */ + @Override + public E get(int index) + { + int dex = 1; + + //if requested index is out of range throw exception + if (index < 0 || index > (size - 1)) { + throw new IndexOutOfBoundsException( + "Index must be in the Range 0-" + (size - 1)); + //else find Node at index + } else { + //head is always at index 0 + if (index == 0) { + return head.data; + } else { + Node current = head; + while(dex <= index) { + current = current.next; + dex++; + } + return current.data; + } + } + } + + /** + * Set (save) an item at a specified index. Previous + * item at that index is overwritten. + * + * @param index the index where the item should be saved + * @param item the item to be saved + */ + @Override + public void set(int index, E item) + { + if (index < 0 || index >= size) { + throw new IndexOutOfBoundsException("Specified Index Must Be " + + "In the Range of 0-" + (size - 1)); + } else { + Node newNode = new Node(item); + Node current = head; + + if (index == 0) { + if (head != null) { + newNode.next = head.next; + } head = newNode; + + } else if (index == (size - 1)) { + while (current.next.next != null) { + current = current.next; + } current.next = newNode; + + } else { + for (int i = 1; i < index; i++) { + current = current.next; + } + newNode.next = current.next.next; + current.next = newNode; + } + } + } + + /** + * Remove item at the front of the list. + * + * @return the item that was removed + */ + @Override + public E removeFront() + { + if (head != null) { + E removedData = head.data; + if (head.next != null) { + head = head.next; + } else { + head = null; + } + size--; + return removedData; + } return null; + } + + /** + * Remove item at the back of the list + * + * @return the item that was removed + */ + @Override + public E removeBack() + { + if (head != null) { + Node current = head; + + if (current.next != null) { + while (current.next.next != null) { + current = current.next; + } + E removedData = current.next.data; + current.next = null; + size--; + return removedData; + } else { + E removedData = head.data; + head = null; + size = 0; + return removedData; + } + } return null; + } + + /** + * Remove item from the list + * + * @param item the item to be removed + */ + @Override + public void remove(E item) + { + if (this.contains(item)) { + Node current = head; + if (head.data.equals(item)) { + removeFront(); + } else { + while (!current.next.data.equals(item)) { + current = current.next; + } + current.next = current.next.next; + size--; + } + } + } + + /** + * Remove item at a specified index. + * + * @param index the index where the item should be removed + * @return the item that was removed + */ + @Override + public E remove(int index) + { + int dex = 1; + E removedData; + + //if requested index is out of range throw exception + if (index < 0 || index > (size - 1)) { + throw new IndexOutOfBoundsException( + "Index must be in the Range 0-" + (size - 1)); + } else { + //check if index is head + if (index == 0) { + removedData = head.data; + removeFront(); + } else { + Node current = head; + while (dex <= index - 1) { + current = current.next; + dex++; + } + removedData = current.next.data; + current.next = current.next.next; + size--; + } + return removedData; + } + } + + /** + * 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) + { + if (head != null) { + Node current = head; + if (current.data.equals(item)) { + return true; + } else { + while (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(); + } + + private class LinkedListIterator implements Iterator { + + private Node current; + + 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 + */ + @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 (current == null) { + throw new NoSuchElementException("There is no next one to go to!"); + } + E dataValue = current.data; + current = current.next; + return dataValue; + } + + @Override + public String toString() { + return "LinkedListIterator{" + + "current=" + current + + '}'; + } + } + + + + @Override + public String toString() { + Node current = head; + String list = "LinkedIntList{size=" + size + ", list=["; + + if (current == null) { + list += "]}"; + } else { + while (current != null) { + list += current.data; + if (current.next != null) { + list += ", "; + } else { + list += "]}"; + } + current = current.next; + } + } return list; + } +} diff --git a/src/driver/Main.java b/src/driver/Main.java index 9ab4bf6..ec895a8 100644 --- a/src/driver/Main.java +++ b/src/driver/Main.java @@ -1,6 +1,7 @@ package driver; import abstractDataTypes.ArrayList; +import abstractDataTypes.LinkedList; //TIP To Run code, press or // click the icon in the gutter. @@ -24,73 +25,141 @@ public static void main(String[] args) { // to see how IntelliJ IDEA suggests fixing it. System.out.println("Hello and welcome!"); - class Cat { - private String breed; +// class Cat { +// private String breed; +// +// public Cat(String breed) { +// this.breed = breed; +// } +// +// @Override +// public String toString() { +// return breed; +// } +// } +// +// String[] breeds = new String[]{ +// "Tabby", "Siamese", "Calico"}; +// +// ArrayList listOfObjects = new ArrayList<>(); +// listOfObjects.addFront(10); +// listOfObjects.addFront("Fresno"); +// listOfObjects.addFront(ITERATIONS); +// listOfObjects.addFront('a'); +// listOfObjects.addFront(new Cat(breeds[1])); +// listOfObjects.addFront(breeds); +// +// System.out.println(listOfObjects); +// +// listOfObjects.addBack(new Cat(breeds[0])); +// listOfObjects.addBack(new Cat(breeds[1])); +// listOfObjects.addBack(new Cat(breeds[0])); +// listOfObjects.addBack(new Cat(breeds[0])); +// listOfObjects.addBack(new Cat(breeds[0])); +// listOfObjects.addBack(new Cat(breeds[0])); +// System.out.println(listOfObjects); +// +// listOfObjects.set(0, 0); +// System.out.println(listOfObjects); +// +// listOfObjects.set((listOfObjects.size() -1), (listOfObjects.size() - 1)); +// listOfObjects.set(0, "front"); +// System.out.println(listOfObjects.size()); +// System.out.println(listOfObjects); +// +// System.out.println(listOfObjects.removeFront()); +// System.out.println(listOfObjects.removeFront()); +// System.out.println(listOfObjects.removeBack()); +// System.out.println(listOfObjects.removeBack()); +// Cat lion = new Cat("Lion"); +// listOfObjects.addFront(lion); +// +// System.out.println(listOfObjects.contains(lion)); +// listOfObjects.removeBack(); +// listOfObjects.removeBack(); +// listOfObjects.removeBack(); +// listOfObjects.removeBack(); +// listOfObjects.removeBack(); +// System.out.println(listOfObjects.contains("Fresn!")); +// +// System.out.println(listOfObjects); +// +// System.out.println(listOfObjects.contains('a')); +// +// System.out.println(); +// System.out.println(listOfObjects); +// listOfObjects.remove((Object) 'a'); +// System.out.println(listOfObjects); +// +// System.out.println(listOfObjects.remove(0)); +// System.out.println(listOfObjects); + + + + + + + // LinkedList Tests + + LinkedList linkedList = new LinkedList<>(); + + linkedList.addFront("Toby"); + linkedList.addFront(Math.random()); + linkedList.addFront('%'); + + linkedList.addBack(3); + linkedList.addBack(4); + linkedList.addBack(5); + + linkedList.add(3, "Middle"); + linkedList.add(0, "Front"); + linkedList.add(8, "End"); + + System.out.println(linkedList); - public Cat(String breed) { - this.breed = breed; - } + System.out.println(linkedList.get(3)); + + System.out.println(linkedList.contains(Math.random())); + + System.out.println(linkedList); + + linkedList.set(0, "Tobiah"); + linkedList.set(8, "Howdy"); + linkedList.set(4, "Howdy"); + System.out.println(linkedList); + + System.out.println(linkedList.removeFront()); + System.out.println(linkedList); + System.out.println(linkedList.removeFront()); + System.out.println(linkedList); + System.out.println(linkedList.removeFront()); + System.out.println(linkedList); + + System.out.println(linkedList.removeBack()); + System.out.println(linkedList); + System.out.println(linkedList.removeBack()); + System.out.println(linkedList); + + linkedList.remove("Toby"); + System.out.println(linkedList); + +// linkedList.remove((Object) 4); +// System.out.println(linkedList); +// linkedList.remove((Object) 3); +// System.out.println(linkedList); +// linkedList.remove("Howdy"); +// System.out.println(linkedList); +// linkedList.remove((Object) null); +// System.out.println(linkedList); +// linkedList.remove("Howdy"); +// System.out.println(linkedList); + + System.out.println(linkedList.remove(0)); + System.out.println(linkedList); - @Override - public String toString() { - return breed; - } - } - String[] breeds = new String[]{ - "Tabby", "Siamese", "Calico"}; - - ArrayList listOfObjects = new ArrayList<>(); - listOfObjects.addFront(10); - listOfObjects.addFront("Fresno"); - listOfObjects.addFront(ITERATIONS); - listOfObjects.addFront('a'); - listOfObjects.addFront(new Cat(breeds[1])); - listOfObjects.addFront(breeds); - - System.out.println(listOfObjects); - - listOfObjects.addBack(new Cat(breeds[0])); - listOfObjects.addBack(new Cat(breeds[1])); - listOfObjects.addBack(new Cat(breeds[0])); - listOfObjects.addBack(new Cat(breeds[0])); - listOfObjects.addBack(new Cat(breeds[0])); - listOfObjects.addBack(new Cat(breeds[0])); - System.out.println(listOfObjects); - - listOfObjects.set(0, 0); - System.out.println(listOfObjects); - - listOfObjects.set((listOfObjects.size() -1), (listOfObjects.size() - 1)); - listOfObjects.set(0, "front"); - System.out.println(listOfObjects.size()); - System.out.println(listOfObjects); - - System.out.println(listOfObjects.removeFront()); - System.out.println(listOfObjects.removeFront()); - System.out.println(listOfObjects.removeBack()); - System.out.println(listOfObjects.removeBack()); - Cat lion = new Cat("Lion"); - listOfObjects.addFront(lion); - - System.out.println(listOfObjects.contains(lion)); - listOfObjects.removeBack(); - listOfObjects.removeBack(); - listOfObjects.removeBack(); - listOfObjects.removeBack(); - listOfObjects.removeBack(); - System.out.println(listOfObjects.contains("Fresn!")); - - System.out.println(listOfObjects); - System.out.println(listOfObjects.contains('a')); - System.out.println(); - System.out.println(listOfObjects); - listOfObjects.remove((Object) 'a'); - System.out.println(listOfObjects); - System.out.println(listOfObjects.remove(0)); - System.out.println(listOfObjects); } } \ No newline at end of file From f7dd69f313d778dd6b1e10d364e7f6478b4ace3e Mon Sep 17 00:00:00 2001 From: tobygoetz Date: Tue, 13 Feb 2024 00:20:03 -0800 Subject: [PATCH 05/10] Finished 1C and Algorithmic Analysis with Code Modeling and Asymptotic Assertions for ArrayList.java --- src/abstractDataTypes/ArrayList.java | 270 ++++++++++++++++++--------- 1 file changed, 183 insertions(+), 87 deletions(-) diff --git a/src/abstractDataTypes/ArrayList.java b/src/abstractDataTypes/ArrayList.java index ccbb8af..d8aeec0 100644 --- a/src/abstractDataTypes/ArrayList.java +++ b/src/abstractDataTypes/ArrayList.java @@ -33,27 +33,40 @@ public ArrayList() /** * Add item to the front. * + * (7(size) + 3) + (5(BL) + 6) == 15(size) + 9 at worst + * 7(size) + 3 at best + * 0(size) + * This function is linear because it reassigns all values to the + * index proceeding it, but calls resize() which is equivalently + * linear as well. + * * @param item the item to be added */ @Override public void addFront(E item) { //loop while index is greater than zero - for (int i = size; i > 0; i--) { + for (int i = size; i > 0; i--) { // { 1 + 1 + 2 = 4 //if buffer is at capacity increase buffer by one index - if (size == buffer.length) { - this.resize(buffer.length + 1); + if (size == buffer.length) { // 1 + this.resize(buffer.length + 1); // f(n)= 5BL + 6 + 1 == O(n) } //index at highest buffer gets shifted right - buffer[i] = buffer[i - 1]; + buffer[i] = buffer[i - 1]; // 1 + 1 } * size } - buffer[0] = (E) item; - size++; - } + buffer[0] = (E) item; // 1 + size++; // 2 + } // == f(size)= 7(n) + 8(n) + 3 /** * Add item to the back. * + * (5BL + 6) + 3 = 5BL + 9 at worst + * f(n) = 2 at best + * This function is constant at best and linear at worst. + * Function is only linear if buffer needs to resize to + * accomadate for 1 additional index + * * @param item the item to be added */ @Override @@ -71,94 +84,121 @@ public void addBack(E item) /** * Add an item at specified index (position). * + * (7 + n)(size - index) + (6 + n) at worst + * O(3 + n) constant at best + * + * This function is linear at worst because it iterates (size - index) times + * and constant at best when invalid index throws exception which I am + * assuming is a constant constructor call. + * * @param index the index where the item should be added * @param item the item to be added */ @Override public void add(int index, E item) { - if (index < 0 || index > size) { - throw new IndexOutOfBoundsException("Specified Index Must Be " + + if (index < 0 || index > size) { // 3 + throw new IndexOutOfBoundsException("Specified Index Must Be " + // + n "In the Range of 0-" + size); } else { //loop while index is greater than index value specified - for (int i = size; i >= index; i--) { + for (int i = size; i >= index; i--) { // { 4 //if buffer is at capacity increase buffer by one index - if (size == buffer.length) { - this.resize(buffer.length + 1); + if (size == buffer.length) { // 1 + this.resize(buffer.length + 1); // 5BL + 6 } //index at highest buffer gets shifted right - if (i != 0) { - buffer[i] = buffer[i - 1]; - } + if (i != 0) { // 1 + buffer[i] = buffer[i - 1]; // 1 } * (size - index) + } // == (7 + n)(size - index) + (6 + n) } } - buffer[index] = item; - size++; + buffer[index] = item; // 1 + size++; // 2 } /** * Get the item at a specified index. * + * O(2 + n) at worst + * O(3) at best + * + * This function is linear across assuming that + * thrown exception is a relative linear constructor call and + * accounting for branches (I presume) + * * @param index the index where the item should be retrieved * @return the item located at that index */ @Override public E get(int index) { - if (index < 0 ) { - throw new IndexOutOfBoundsException( + if (index < 0 ) { // 1 + throw new IndexOutOfBoundsException( // n "Index must be greater than 0"); - } else if (index >= size ) { - if (size == 0) { - throw new IndexOutOfBoundsException( + } else if (index >= size ) { // 1 + if (size == 0) { // 1 + throw new IndexOutOfBoundsException( // n "This list is empty"); } else { - throw new IndexOutOfBoundsException( + throw new IndexOutOfBoundsException( // n "Specified Index Must Be " + - "In the Range of 0-" + (size - 1)); + "In the Range of 0-" + (size - 1)); // 1 } - } return buffer[index]; + } return buffer[index]; // 1 } /** * Set (save) an item at a specified index. Previous * item at that index is overwritten. * + * O(3 + 1) at best + * O(4 + n) at worst + * This function is constant'ish but still technically linear + * because if O(3) = O(3 * n), then n = 1. Boom math... + * I want to say constant because I know a fixed amount at worst + * and at best, but not as constant as size() + * * @param index the index where the item should be saved * @param item the item to be saved */ @Override public void set(int index, E item) { - if (index < 0 || index >= size) { - throw new IndexOutOfBoundsException("Specified Index Must Be " + - "In the Range of 0-" + (size - 1)); + if (index < 0 || index >= size) { // 3 + throw new IndexOutOfBoundsException("Specified Index Must Be " + // n + "In the Range of 0-" + (size - 1)); // 1 } else { - buffer[index] = item; + buffer[index] = item; // 1 } } /** * Remove item at the front of the list. * + * (6(size - 2) + 8) + ((5BL + 6) +2) + * O(BL) at worst + * O(size - 2) at best if buffer does not need to resize + * This function is linear because it iterates over entire + * array and possibly again through resize() + * * @return the item that was removed */ @Override public E removeFront() { - if (!isEmpty()) { - E removed = buffer[0]; - for (int i = 0; i <= size - 2; i++) { - buffer[i] = buffer[i + 1]; - } size--; + if (!isEmpty()) { // 1 + O(3) + E removed = buffer[0]; // 1 + for (int i = 0; i <= size - 2; i++) { // { 4 + buffer[i] = buffer[i + 1]; // 1 + 1 } * (size - 2) + } size--; // 2 //Reduce buffer until original buffer size is reached - if (size >= 10) { - resize(size); + if (size >= 10) { // 1 + resize(size); // 5BL + 6 //after buffer becomes 10 set removed values back to null } else { - buffer[size] = null; + buffer[size] = null; // 1 } return removed; } else { @@ -169,15 +209,19 @@ public E removeFront() /** * Remove item at the back of the list * + * O(1) at best?? + * O(9) at worst + * Constant at best because return null is an assignment'ish + * * @return the item that was removed */ @Override public E removeBack() { - if (!isEmpty()) { - E removed = buffer[size - 1]; - buffer[size - 1] = null; - size--; + if (!isEmpty()) { // O(3) + E removed = buffer[size - 1]; // 1 + 1 + buffer[size - 1] = null; // 1 + 1 + size--; // 2 return removed; } else { return null; @@ -187,30 +231,38 @@ public E removeBack() /** * Remove item from the list * + * (3 + BL) or O(12) or (11(size - 1) + 3) + 3 + O(size) + 5BL + 6) + * + * so 0(2n) at worst + * This function could definitely been written cleaner but in Britain + * they have phrase 'any road' meaning you'll always get there as long + * as you keep driving... My logic took a binary search approach to finding + * the answer, but instead of analyzing one or the other I analyzed both. + * * @param item the item to be removed */ @Override public void remove(E item) { - if (this.contains(item)) { - if (this.buffer[0].equals(item)) { - this.removeFront(); - } else if (this.buffer[size - 1].equals(item)) { - this.removeBack(); + if (this.contains(item)) { // 0(size) + if (this.buffer[0].equals(item)) { // 1array access + 1 conditional + this.removeFront(); // 0(BL) + } else if (this.buffer[size - 1].equals(item)) { // 1 + 1 + 1 + this.removeBack(); // 0(9) } else { - int index = 0; - while (!buffer[index].equals(item)) { - index++; + int index = 0; // 1 + while (!buffer[index].equals(item)) { // { 1 + 1 + index++; // 1 + 1 } * (BL - B[i]) } - for (int i = index; i < size - 1; i++) { - buffer[i] = buffer[i + 1]; + for (int i = index; i < size - 1; i++) { // { 4 + buffer[i] = buffer[i + 1]; // 1 + 1 } * size - 1 } - size--; - if (size >= 10) { - resize(size); + size--; // 2 + if (size >= 10) { // 1 + resize(size); // 5BL + 6 //after buffer becomes 10 set removed values back to null } else { - buffer[size] = null; + buffer[size] = null; // 1 + 1 } } } @@ -219,6 +271,15 @@ public void remove(E item) /** * Remove item at a specified index. * + * (((8(size -1) + 4) + 2) + 2) + 1) + * O(size - 1) at worst + * O(2) at best + * + * Almost constant on invalid input but linear if removing any index + * but the index at the back of array, I think I accounted for branching + * in this one. My assumption is don't include unreachable code in + * the calculation of the y-axis, but probably the conditionals themselves. + * * @param index the index where the item should be removed * @return the item that was removed */ @@ -226,77 +287,96 @@ public void remove(E item) public E remove(int index) { // first, check the index to see if it is valid - if (index < 0) { - throw new IndexOutOfBoundsException("Index cannot be negative"); - } else if (index >= size) { - throw new IndexOutOfBoundsException("Index is higher than size"); + if (index < 0) { // 1 + throw new IndexOutOfBoundsException("Index cannot be negative"); // 1 + } else if (index >= size) { // 1 + throw new IndexOutOfBoundsException("Index is higher than size"); // 1 } // save a copy of the value to be removed so that we can return it later - E copyOfRemovedValue = buffer[index]; + E copyOfRemovedValue = buffer[index]; // 1 + 1 // if index is last index with valid data, set data to null - if (index == size - 1) { - buffer[index] = null; + if (index == size - 1) { // 1 + 1 + buffer[index] = null; // 1 + 1 // shift all values over starting at index to be removed - } else { - for (int i = index; i < size - 1; i++) { + } else { // { 4 + for (int i = index; i < size - 1; i++) { // 1 + 1 + 1 + 1 } * (size - 1) buffer[i] = buffer[i + 1]; } - } size--; + } size--; // 2 // set trailing index to null to account for reduced size - buffer[size] = null; + buffer[size] = null; // 1 + 1 - return copyOfRemovedValue; + return copyOfRemovedValue; // 1 } /** * Checks if an item is in the list. * + * O(size) at worst + * O(1) at best + * + * This function is linear but constant in the case that an + * array is empty + * * @param item the item to search for * @return true if the item is in the list, false otherwise */ @Override public boolean contains(Object item) { - int index = 0; - while (index != size) { - if (buffer[index].equals(item)) { - return true; + int index = 0; // 1 + while (index != size) { // { 1 + if (buffer[index].equals(item)) { // 1 + 1 + return true; // 1 } else { - index++; + index++; // 1 + 1 } * size } - } return false; + } return false; // 1 } /** * Checks if the list is empty. * + * 0(3) at best and worst + * This method is constant and will always be constant'ish + * but linear for all intesive purposes + * * @return true if the list is empty, false otherwise */ @Override public boolean isEmpty() { - return size == 0 && buffer[0] == null; + return size == 0 && buffer[0] == null; // 3 } /** * Provides a count of the number of items in the list. * + * O(1) at best and worst + * Doesn't get much better than this + * * @return number of items in the list */ @Override public int size() { - return size; + return size; // 1 } /** * Returns an iterator over elements of type {@code T}. * + * O(2) at best?? + * + * I wouldn't know if the constructor is this.iterator = iterator + * because it's implicit and can't remeber nor find how to look + * up imported static function calls in intellij + * * @return an Iterator. */ @Override public Iterator iterator() { - return new ArrayListIterator(); + return new ArrayListIterator(); // 1 + 1'ish } private class ArrayListIterator implements Iterator { @@ -338,31 +418,47 @@ public E next() { /** * Helper method to resize ArrayIntlist to support * more data + * + * f(BL) = 5BL + 6 + * O(n) at worst and at best + * This function is linear at worst because it loops over all existing + * indices in the buffer and still linear but insignificantly faster + * if new buffer is less than existing buffer */ private void resize(int newSize) { //create new space, separate from the old space (buffer) // int newSize = size + CAPACITY; - E[] newBuffer = (E[]) new Object[newSize]; + E[] newBuffer = (E[]) new Object[newSize]; // 1 + 3 (Assuming that new object is constant) // copy everything over from buffer into newBuffer - if (newSize > buffer.length) { - for (int i = 0; i < buffer.length; i++) { - newBuffer[i] = buffer[i]; - } - } else { - for (int i = 0; i < newBuffer.length; i++) { - newBuffer[i] = buffer[i]; - } + if (newSize > buffer.length) { // 1 + for (int i = 0; i < buffer.length; i++) { // { 1 + 1 + 2 (i = i + 1) * BL + newBuffer[i] = buffer[i]; // 1 } == 5BL + 6 + } // + } else { // + for (int i = 0; i < newBuffer.length; i++) { // { 1 + 1 + 2 * NBL + newBuffer[i] = buffer[i]; // 1 } == 5BL + 6 + } // } // set the new space into buffer - buffer = newBuffer; + buffer = newBuffer; // 1 // the old space is no longer "pointed to" and will eventually // be cleaned up by the garbage collector } - + /** + * If I remember right Strings are objects which are arrays of characters, + * thus a new String = an iteration over an array to build that string. + * So that being, each new String here is actually 0(String.length) + + * operands + static method call to toString which probably iterates again... + * + * O(bigNumber * character) + few operands + * 0(n) at worst... + * + * @return + */ @Override public String toString() { return "ArrayList{" + From 1d9b7b2cb1f920374386a8e14f56a68bc54f4b94 Mon Sep 17 00:00:00 2001 From: tobygoetz Date: Tue, 13 Feb 2024 00:23:57 -0800 Subject: [PATCH 06/10] Fixed typos and documentation... --- src/abstractDataTypes/ArrayList.java | 29 ++++------------------------ 1 file changed, 4 insertions(+), 25 deletions(-) diff --git a/src/abstractDataTypes/ArrayList.java b/src/abstractDataTypes/ArrayList.java index d8aeec0..c564a48 100644 --- a/src/abstractDataTypes/ArrayList.java +++ b/src/abstractDataTypes/ArrayList.java @@ -32,7 +32,6 @@ public ArrayList() /** * Add item to the front. - * * (7(size) + 3) + (5(BL) + 6) == 15(size) + 9 at worst * 7(size) + 3 at best * 0(size) @@ -60,12 +59,11 @@ public void addFront(E item) /** * Add item to the back. - * * (5BL + 6) + 3 = 5BL + 9 at worst * f(n) = 2 at best * This function is constant at best and linear at worst. * Function is only linear if buffer needs to resize to - * accomadate for 1 additional index + * accommodate for 1 additional index * * @param item the item to be added */ @@ -83,10 +81,8 @@ public void addBack(E item) /** * Add an item at specified index (position). - * * (7 + n)(size - index) + (6 + n) at worst * O(3 + n) constant at best - * * This function is linear at worst because it iterates (size - index) times * and constant at best when invalid index throws exception which I am * assuming is a constant constructor call. @@ -119,10 +115,8 @@ public void add(int index, E item) /** * Get the item at a specified index. - * * O(2 + n) at worst * O(3) at best - * * This function is linear across assuming that * thrown exception is a relative linear constructor call and * accounting for branches (I presume) @@ -151,7 +145,6 @@ public E get(int index) /** * Set (save) an item at a specified index. Previous * item at that index is overwritten. - * * O(3 + 1) at best * O(4 + n) at worst * This function is constant'ish but still technically linear @@ -175,7 +168,6 @@ public void set(int index, E item) /** * Remove item at the front of the list. - * * (6(size - 2) + 8) + ((5BL + 6) +2) * O(BL) at worst * O(size - 2) at best if buffer does not need to resize @@ -208,7 +200,6 @@ public E removeFront() /** * Remove item at the back of the list - * * O(1) at best?? * O(9) at worst * Constant at best because return null is an assignment'ish @@ -230,9 +221,7 @@ public E removeBack() /** * Remove item from the list - * * (3 + BL) or O(12) or (11(size - 1) + 3) + 3 + O(size) + 5BL + 6) - * * so 0(2n) at worst * This function could definitely been written cleaner but in Britain * they have phrase 'any road' meaning you'll always get there as long @@ -270,11 +259,9 @@ public void remove(E item) /** * Remove item at a specified index. - * * (((8(size -1) + 4) + 2) + 2) + 1) * O(size - 1) at worst * O(2) at best - * * Almost constant on invalid input but linear if removing any index * but the index at the back of array, I think I accounted for branching * in this one. My assumption is don't include unreachable code in @@ -313,10 +300,8 @@ public E remove(int index) /** * Checks if an item is in the list. - * * O(size) at worst * O(1) at best - * * This function is linear but constant in the case that an * array is empty * @@ -338,10 +323,9 @@ public boolean contains(Object item) /** * Checks if the list is empty. - * * 0(3) at best and worst * This method is constant and will always be constant'ish - * but linear for all intesive purposes + * but linear for all intents and purposes * * @return true if the list is empty, false otherwise */ @@ -352,7 +336,6 @@ public boolean isEmpty() { /** * Provides a count of the number of items in the list. - * * O(1) at best and worst * Doesn't get much better than this * @@ -365,11 +348,9 @@ public int size() { /** * Returns an iterator over elements of type {@code T}. - * * O(2) at best?? - * * I wouldn't know if the constructor is this.iterator = iterator - * because it's implicit and can't remeber nor find how to look + * because it's implicit and can't remember nor find how to look * up imported static function calls in intellij * * @return an Iterator. @@ -418,7 +399,6 @@ public E next() { /** * Helper method to resize ArrayIntlist to support * more data - * * f(BL) = 5BL + 6 * O(n) at worst and at best * This function is linear at worst because it loops over all existing @@ -453,11 +433,10 @@ private void resize(int newSize) { * thus a new String = an iteration over an array to build that string. * So that being, each new String here is actually 0(String.length) + * operands + static method call to toString which probably iterates again... - * * O(bigNumber * character) + few operands * 0(n) at worst... * - * @return + * @return String representation of ArrayList */ @Override public String toString() { From df2d68afee5499a6454291b173da41651f59eeee Mon Sep 17 00:00:00 2001 From: tobygoetz Date: Tue, 13 Feb 2024 01:23:55 -0800 Subject: [PATCH 07/10] Added ArrayListTest and restructured package --- SDEV333-Term-Project.iml | 17 + src/abstractDataTypes/ArrayList.java | 449 -------------------------- src/abstractDataTypes/LinkedList.java | 427 ------------------------ src/driver/Main.java | 165 ---------- src/interfaces/Deque.java | 45 --- src/interfaces/List.java | 87 ----- src/interfaces/MathSet.java | 105 ------ src/interfaces/Queue.java | 31 -- src/interfaces/Stack.java | 38 --- tests/ArrayListTest.java | 337 +++++++++++++++++++ 10 files changed, 354 insertions(+), 1347 deletions(-) delete mode 100644 src/abstractDataTypes/ArrayList.java delete mode 100644 src/abstractDataTypes/LinkedList.java delete mode 100644 src/driver/Main.java delete mode 100644 src/interfaces/Deque.java delete mode 100644 src/interfaces/List.java delete mode 100644 src/interfaces/MathSet.java delete mode 100644 src/interfaces/Queue.java delete mode 100644 src/interfaces/Stack.java create mode 100644 tests/ArrayListTest.java diff --git a/SDEV333-Term-Project.iml b/SDEV333-Term-Project.iml index c90834f..0f9e336 100644 --- a/SDEV333-Term-Project.iml +++ b/SDEV333-Term-Project.iml @@ -4,8 +4,25 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/abstractDataTypes/ArrayList.java b/src/abstractDataTypes/ArrayList.java deleted file mode 100644 index c564a48..0000000 --- a/src/abstractDataTypes/ArrayList.java +++ /dev/null @@ -1,449 +0,0 @@ -package abstractDataTypes; - -import interfaces.List; - -import java.util.Arrays; -import java.util.Iterator; -import java.util.NoSuchElementException; - -/** - * @author tobygoetz - * @version 1.0 - * Generic ArrayList, to be used with any data type - * @param specifies data type to be used in ArrayList - */ -public class ArrayList implements List { - - private static final int CAPACITY = 10; - - // fields - private E[] buffer; - private int size; - - /** - * Constructor for ArrayList - */ - public ArrayList() - { - size = 0; - buffer = (E[]) new Object[CAPACITY]; - } - - - /** - * Add item to the front. - * (7(size) + 3) + (5(BL) + 6) == 15(size) + 9 at worst - * 7(size) + 3 at best - * 0(size) - * This function is linear because it reassigns all values to the - * index proceeding it, but calls resize() which is equivalently - * linear as well. - * - * @param item the item to be added - */ - @Override - public void addFront(E item) - { - //loop while index is greater than zero - for (int i = size; i > 0; i--) { // { 1 + 1 + 2 = 4 - //if buffer is at capacity increase buffer by one index - if (size == buffer.length) { // 1 - this.resize(buffer.length + 1); // f(n)= 5BL + 6 + 1 == O(n) - } - //index at highest buffer gets shifted right - buffer[i] = buffer[i - 1]; // 1 + 1 } * size - } - buffer[0] = (E) item; // 1 - size++; // 2 - } // == f(size)= 7(n) + 8(n) + 3 - - /** - * Add item to the back. - * (5BL + 6) + 3 = 5BL + 9 at worst - * f(n) = 2 at best - * This function is constant at best and linear at worst. - * Function is only linear if buffer needs to resize to - * accommodate for 1 additional index - * - * @param item the item to be added - */ - @Override - public void addBack(E item) - { - //if buffer is at capacity increase buffer by one index - if ( size == buffer.length) { - resize(size + 1); - } - //add value to size which is one index greater than last value - buffer[size] = item; - size++; - } - - /** - * Add an item at specified index (position). - * (7 + n)(size - index) + (6 + n) at worst - * O(3 + n) constant at best - * This function is linear at worst because it iterates (size - index) times - * and constant at best when invalid index throws exception which I am - * assuming is a constant constructor call. - * - * @param index the index where the item should be added - * @param item the item to be added - */ - @Override - public void add(int index, E item) - { - if (index < 0 || index > size) { // 3 - throw new IndexOutOfBoundsException("Specified Index Must Be " + // + n - "In the Range of 0-" + size); - } else { - //loop while index is greater than index value specified - for (int i = size; i >= index; i--) { // { 4 - //if buffer is at capacity increase buffer by one index - if (size == buffer.length) { // 1 - this.resize(buffer.length + 1); // 5BL + 6 - } - //index at highest buffer gets shifted right - if (i != 0) { // 1 - buffer[i] = buffer[i - 1]; // 1 } * (size - index) - } // == (7 + n)(size - index) + (6 + n) - } - } - buffer[index] = item; // 1 - size++; // 2 - } - - /** - * Get the item at a specified index. - * O(2 + n) at worst - * O(3) at best - * This function is linear across assuming that - * thrown exception is a relative linear constructor call and - * accounting for branches (I presume) - * - * @param index the index where the item should be retrieved - * @return the item located at that index - */ - @Override - public E get(int index) - { - if (index < 0 ) { // 1 - throw new IndexOutOfBoundsException( // n - "Index must be greater than 0"); - } else if (index >= size ) { // 1 - if (size == 0) { // 1 - throw new IndexOutOfBoundsException( // n - "This list is empty"); - } else { - throw new IndexOutOfBoundsException( // n - "Specified Index Must Be " + - "In the Range of 0-" + (size - 1)); // 1 - } - } return buffer[index]; // 1 - } - - /** - * Set (save) an item at a specified index. Previous - * item at that index is overwritten. - * O(3 + 1) at best - * O(4 + n) at worst - * This function is constant'ish but still technically linear - * because if O(3) = O(3 * n), then n = 1. Boom math... - * I want to say constant because I know a fixed amount at worst - * and at best, but not as constant as size() - * - * @param index the index where the item should be saved - * @param item the item to be saved - */ - @Override - public void set(int index, E item) - { - if (index < 0 || index >= size) { // 3 - throw new IndexOutOfBoundsException("Specified Index Must Be " + // n - "In the Range of 0-" + (size - 1)); // 1 - } else { - buffer[index] = item; // 1 - } - } - - /** - * Remove item at the front of the list. - * (6(size - 2) + 8) + ((5BL + 6) +2) - * O(BL) at worst - * O(size - 2) at best if buffer does not need to resize - * This function is linear because it iterates over entire - * array and possibly again through resize() - * - * @return the item that was removed - */ - @Override - public E removeFront() - { - if (!isEmpty()) { // 1 + O(3) - E removed = buffer[0]; // 1 - for (int i = 0; i <= size - 2; i++) { // { 4 - buffer[i] = buffer[i + 1]; // 1 + 1 } * (size - 2) - } size--; // 2 - - //Reduce buffer until original buffer size is reached - if (size >= 10) { // 1 - resize(size); // 5BL + 6 - //after buffer becomes 10 set removed values back to null - } else { - buffer[size] = null; // 1 - } - return removed; - } else { - return null; - } - } - - /** - * Remove item at the back of the list - * O(1) at best?? - * O(9) at worst - * Constant at best because return null is an assignment'ish - * - * @return the item that was removed - */ - @Override - public E removeBack() - { - if (!isEmpty()) { // O(3) - E removed = buffer[size - 1]; // 1 + 1 - buffer[size - 1] = null; // 1 + 1 - size--; // 2 - return removed; - } else { - return null; - } - } - - /** - * Remove item from the list - * (3 + BL) or O(12) or (11(size - 1) + 3) + 3 + O(size) + 5BL + 6) - * so 0(2n) at worst - * This function could definitely been written cleaner but in Britain - * they have phrase 'any road' meaning you'll always get there as long - * as you keep driving... My logic took a binary search approach to finding - * the answer, but instead of analyzing one or the other I analyzed both. - * - * @param item the item to be removed - */ - @Override - public void remove(E item) - { - if (this.contains(item)) { // 0(size) - if (this.buffer[0].equals(item)) { // 1array access + 1 conditional - this.removeFront(); // 0(BL) - } else if (this.buffer[size - 1].equals(item)) { // 1 + 1 + 1 - this.removeBack(); // 0(9) - } else { - int index = 0; // 1 - while (!buffer[index].equals(item)) { // { 1 + 1 - index++; // 1 + 1 } * (BL - B[i]) - } - for (int i = index; i < size - 1; i++) { // { 4 - buffer[i] = buffer[i + 1]; // 1 + 1 } * size - 1 - } - size--; // 2 - if (size >= 10) { // 1 - resize(size); // 5BL + 6 - //after buffer becomes 10 set removed values back to null - } else { - buffer[size] = null; // 1 + 1 - } - } - } - } - - /** - * Remove item at a specified index. - * (((8(size -1) + 4) + 2) + 2) + 1) - * O(size - 1) at worst - * O(2) at best - * Almost constant on invalid input but linear if removing any index - * but the index at the back of array, I think I accounted for branching - * in this one. My assumption is don't include unreachable code in - * the calculation of the y-axis, but probably the conditionals themselves. - * - * @param index the index where the item should be removed - * @return the item that was removed - */ - @Override - public E remove(int index) - { - // first, check the index to see if it is valid - if (index < 0) { // 1 - throw new IndexOutOfBoundsException("Index cannot be negative"); // 1 - } else if (index >= size) { // 1 - throw new IndexOutOfBoundsException("Index is higher than size"); // 1 - } - - // save a copy of the value to be removed so that we can return it later - E copyOfRemovedValue = buffer[index]; // 1 + 1 - - // if index is last index with valid data, set data to null - if (index == size - 1) { // 1 + 1 - buffer[index] = null; // 1 + 1 - // shift all values over starting at index to be removed - } else { // { 4 - for (int i = index; i < size - 1; i++) { // 1 + 1 + 1 + 1 } * (size - 1) - buffer[i] = buffer[i + 1]; - } - } size--; // 2 - // set trailing index to null to account for reduced size - buffer[size] = null; // 1 + 1 - - return copyOfRemovedValue; // 1 - } - - /** - * Checks if an item is in the list. - * O(size) at worst - * O(1) at best - * This function is linear but constant in the case that an - * array is empty - * - * @param item the item to search for - * @return true if the item is in the list, false otherwise - */ - @Override - public boolean contains(Object item) - { - int index = 0; // 1 - while (index != size) { // { 1 - if (buffer[index].equals(item)) { // 1 + 1 - return true; // 1 - } else { - index++; // 1 + 1 } * size - } - } return false; // 1 - } - - /** - * Checks if the list is empty. - * 0(3) at best and worst - * This method is constant and will always be constant'ish - * but linear for all intents and purposes - * - * @return true if the list is empty, false otherwise - */ - @Override - public boolean isEmpty() { - return size == 0 && buffer[0] == null; // 3 - } - - /** - * Provides a count of the number of items in the list. - * O(1) at best and worst - * Doesn't get much better than this - * - * @return number of items in the list - */ - @Override - public int size() { - return size; // 1 - } - - /** - * Returns an iterator over elements of type {@code T}. - * O(2) at best?? - * I wouldn't know if the constructor is this.iterator = iterator - * because it's implicit and can't remember nor find how to look - * up imported static function calls in intellij - * - * @return an Iterator. - */ - @Override - public Iterator iterator() { - return new ArrayListIterator(); // 1 + 1'ish - } - - private class ArrayListIterator implements Iterator { - - private int index; - - private ArrayListIterator() { index = 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 index < 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 (index >= size) { - throw new NoSuchElementException("Index is out of range"); - } - - E currentValue = buffer[index]; - index++; - return currentValue; - } - } - - /** - * Helper method to resize ArrayIntlist to support - * more data - * f(BL) = 5BL + 6 - * O(n) at worst and at best - * This function is linear at worst because it loops over all existing - * indices in the buffer and still linear but insignificantly faster - * if new buffer is less than existing buffer - */ - private void resize(int newSize) { - //create new space, separate from the old space (buffer) -// int newSize = size + CAPACITY; - E[] newBuffer = (E[]) new Object[newSize]; // 1 + 3 (Assuming that new object is constant) - - // copy everything over from buffer into newBuffer - if (newSize > buffer.length) { // 1 - for (int i = 0; i < buffer.length; i++) { // { 1 + 1 + 2 (i = i + 1) * BL - newBuffer[i] = buffer[i]; // 1 } == 5BL + 6 - } // - } else { // - for (int i = 0; i < newBuffer.length; i++) { // { 1 + 1 + 2 * NBL - newBuffer[i] = buffer[i]; // 1 } == 5BL + 6 - } // - } - - // set the new space into buffer - buffer = newBuffer; // 1 - - // the old space is no longer "pointed to" and will eventually - // be cleaned up by the garbage collector - } - - /** - * If I remember right Strings are objects which are arrays of characters, - * thus a new String = an iteration over an array to build that string. - * So that being, each new String here is actually 0(String.length) + - * operands + static method call to toString which probably iterates again... - * O(bigNumber * character) + few operands - * 0(n) at worst... - * - * @return String representation of ArrayList - */ - @Override - public String toString() { - return "ArrayList{" + - "size=" + size + - ", indices=" + Arrays.toString(buffer) + - - '}'; - } -} diff --git a/src/abstractDataTypes/LinkedList.java b/src/abstractDataTypes/LinkedList.java deleted file mode 100644 index dddea15..0000000 --- a/src/abstractDataTypes/LinkedList.java +++ /dev/null @@ -1,427 +0,0 @@ -package abstractDataTypes; - -import interfaces.List; - -import java.util.Iterator; -import java.util.NoSuchElementException; - -/** - * @author tobygoetz - * @version 1.0 - * - * Generic LinkedList to be used with any data type - * @param - */ -public class LinkedList implements List { - - // Fields - private Node head; - private int size; - - /** - * Constructor to initialize the fields of LinkedIntList - */ - public LinkedList() { - head = null; - size = 0; - } - - // Node Class - private class Node { - private E data; - private Node next; - - /** - * Constuctor for Node that accepts on Integer data - * and sets the next to null - * @param data Integer value of Node - */ - private Node(E data) { - this.data = data; - this.next = null; - } - - /** - * Constuctor for Node that accepts on Integer data - * and sets the next to null - * @param data Integer Value of Node - * @param next Points to the next Node in list - */ - private Node(E data, Node next) { - this.data = data; - this.next = next; - } - - public String toString() { - return data + " -> "; - } - } - - /** - * Add item to the front. - * - * @param item the item to be added - */ - @Override - public void addFront(E item) - { - // new Node to be added - Node addedToFront = new Node(item); - // the list currently has some nodes in it - if (head != null) { - addedToFront.next = head; - } - head = addedToFront; - size++; - } - - /** - * Add item to the back. - * - * @param item the item to be added - */ - @Override - public void addBack(E item) - { - Node addToBack = new Node(item); - - if (head == null) { - head = addToBack; - } else { - Node current = head; - - while (current.next != null) { - current = current.next; - } - current.next = addToBack; - } size++; - } - - /** - * Add an item at specified index (position). - * - * @param index the index where the item should be added - * @param item the item to be added - */ - @Override - public void add(int index, E item) - { - int dex = 1; - //if requested index is out of range throw exception - if (index < 0 || index > (size )) { - throw new IndexOutOfBoundsException( - "Index must be in the Range 0-" + (size)); - //else find Node at index - } else { - //check if index is head - if (index == 0) { - addFront(item); - //check if index is at the end - } else if (index == (size)) { - addBack(item); - //remove everywhere else - } else { - Node current = head; - while (dex <= index - 1) { - current = current.next; - dex++; - } - current.next = new Node(item, current.next); - size++; - } - } - } - - /** - * Get the item at a specified index. - * - * @param index the index where the item should be retrieved - * @return the item located at that index - */ - @Override - public E get(int index) - { - int dex = 1; - - //if requested index is out of range throw exception - if (index < 0 || index > (size - 1)) { - throw new IndexOutOfBoundsException( - "Index must be in the Range 0-" + (size - 1)); - //else find Node at index - } else { - //head is always at index 0 - if (index == 0) { - return head.data; - } else { - Node current = head; - while(dex <= index) { - current = current.next; - dex++; - } - return current.data; - } - } - } - - /** - * Set (save) an item at a specified index. Previous - * item at that index is overwritten. - * - * @param index the index where the item should be saved - * @param item the item to be saved - */ - @Override - public void set(int index, E item) - { - if (index < 0 || index >= size) { - throw new IndexOutOfBoundsException("Specified Index Must Be " + - "In the Range of 0-" + (size - 1)); - } else { - Node newNode = new Node(item); - Node current = head; - - if (index == 0) { - if (head != null) { - newNode.next = head.next; - } head = newNode; - - } else if (index == (size - 1)) { - while (current.next.next != null) { - current = current.next; - } current.next = newNode; - - } else { - for (int i = 1; i < index; i++) { - current = current.next; - } - newNode.next = current.next.next; - current.next = newNode; - } - } - } - - /** - * Remove item at the front of the list. - * - * @return the item that was removed - */ - @Override - public E removeFront() - { - if (head != null) { - E removedData = head.data; - if (head.next != null) { - head = head.next; - } else { - head = null; - } - size--; - return removedData; - } return null; - } - - /** - * Remove item at the back of the list - * - * @return the item that was removed - */ - @Override - public E removeBack() - { - if (head != null) { - Node current = head; - - if (current.next != null) { - while (current.next.next != null) { - current = current.next; - } - E removedData = current.next.data; - current.next = null; - size--; - return removedData; - } else { - E removedData = head.data; - head = null; - size = 0; - return removedData; - } - } return null; - } - - /** - * Remove item from the list - * - * @param item the item to be removed - */ - @Override - public void remove(E item) - { - if (this.contains(item)) { - Node current = head; - if (head.data.equals(item)) { - removeFront(); - } else { - while (!current.next.data.equals(item)) { - current = current.next; - } - current.next = current.next.next; - size--; - } - } - } - - /** - * Remove item at a specified index. - * - * @param index the index where the item should be removed - * @return the item that was removed - */ - @Override - public E remove(int index) - { - int dex = 1; - E removedData; - - //if requested index is out of range throw exception - if (index < 0 || index > (size - 1)) { - throw new IndexOutOfBoundsException( - "Index must be in the Range 0-" + (size - 1)); - } else { - //check if index is head - if (index == 0) { - removedData = head.data; - removeFront(); - } else { - Node current = head; - while (dex <= index - 1) { - current = current.next; - dex++; - } - removedData = current.next.data; - current.next = current.next.next; - size--; - } - return removedData; - } - } - - /** - * 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) - { - if (head != null) { - Node current = head; - if (current.data.equals(item)) { - return true; - } else { - while (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(); - } - - private class LinkedListIterator implements Iterator { - - private Node current; - - 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 - */ - @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 (current == null) { - throw new NoSuchElementException("There is no next one to go to!"); - } - E dataValue = current.data; - current = current.next; - return dataValue; - } - - @Override - public String toString() { - return "LinkedListIterator{" + - "current=" + current + - '}'; - } - } - - - - @Override - public String toString() { - Node current = head; - String list = "LinkedIntList{size=" + size + ", list=["; - - if (current == null) { - list += "]}"; - } else { - while (current != null) { - list += current.data; - if (current.next != null) { - list += ", "; - } else { - list += "]}"; - } - current = current.next; - } - } return list; - } -} diff --git a/src/driver/Main.java b/src/driver/Main.java deleted file mode 100644 index ec895a8..0000000 --- a/src/driver/Main.java +++ /dev/null @@ -1,165 +0,0 @@ -package driver; - -import abstractDataTypes.ArrayList; -import abstractDataTypes.LinkedList; - -//TIP To Run code, press or -// click the icon in the gutter. - -/** - * @author tobygoetz - * @version 1.0 - * Driver class to test ArrayList and LinkedList that - * implement list.java - */ -public class Main { - - public static final int ITERATIONS = 25; - - /** - * program to run Main Class - * @param args command line arguments - */ - public static void main(String[] args) { - //TIP Press with your caret at the highlighted text - // to see how IntelliJ IDEA suggests fixing it. - System.out.println("Hello and welcome!"); - -// class Cat { -// private String breed; -// -// public Cat(String breed) { -// this.breed = breed; -// } -// -// @Override -// public String toString() { -// return breed; -// } -// } -// -// String[] breeds = new String[]{ -// "Tabby", "Siamese", "Calico"}; -// -// ArrayList listOfObjects = new ArrayList<>(); -// listOfObjects.addFront(10); -// listOfObjects.addFront("Fresno"); -// listOfObjects.addFront(ITERATIONS); -// listOfObjects.addFront('a'); -// listOfObjects.addFront(new Cat(breeds[1])); -// listOfObjects.addFront(breeds); -// -// System.out.println(listOfObjects); -// -// listOfObjects.addBack(new Cat(breeds[0])); -// listOfObjects.addBack(new Cat(breeds[1])); -// listOfObjects.addBack(new Cat(breeds[0])); -// listOfObjects.addBack(new Cat(breeds[0])); -// listOfObjects.addBack(new Cat(breeds[0])); -// listOfObjects.addBack(new Cat(breeds[0])); -// System.out.println(listOfObjects); -// -// listOfObjects.set(0, 0); -// System.out.println(listOfObjects); -// -// listOfObjects.set((listOfObjects.size() -1), (listOfObjects.size() - 1)); -// listOfObjects.set(0, "front"); -// System.out.println(listOfObjects.size()); -// System.out.println(listOfObjects); -// -// System.out.println(listOfObjects.removeFront()); -// System.out.println(listOfObjects.removeFront()); -// System.out.println(listOfObjects.removeBack()); -// System.out.println(listOfObjects.removeBack()); -// Cat lion = new Cat("Lion"); -// listOfObjects.addFront(lion); -// -// System.out.println(listOfObjects.contains(lion)); -// listOfObjects.removeBack(); -// listOfObjects.removeBack(); -// listOfObjects.removeBack(); -// listOfObjects.removeBack(); -// listOfObjects.removeBack(); -// System.out.println(listOfObjects.contains("Fresn!")); -// -// System.out.println(listOfObjects); -// -// System.out.println(listOfObjects.contains('a')); -// -// System.out.println(); -// System.out.println(listOfObjects); -// listOfObjects.remove((Object) 'a'); -// System.out.println(listOfObjects); -// -// System.out.println(listOfObjects.remove(0)); -// System.out.println(listOfObjects); - - - - - - - // LinkedList Tests - - LinkedList linkedList = new LinkedList<>(); - - linkedList.addFront("Toby"); - linkedList.addFront(Math.random()); - linkedList.addFront('%'); - - linkedList.addBack(3); - linkedList.addBack(4); - linkedList.addBack(5); - - linkedList.add(3, "Middle"); - linkedList.add(0, "Front"); - linkedList.add(8, "End"); - - System.out.println(linkedList); - - System.out.println(linkedList.get(3)); - - System.out.println(linkedList.contains(Math.random())); - - System.out.println(linkedList); - - linkedList.set(0, "Tobiah"); - linkedList.set(8, "Howdy"); - linkedList.set(4, "Howdy"); - System.out.println(linkedList); - - System.out.println(linkedList.removeFront()); - System.out.println(linkedList); - System.out.println(linkedList.removeFront()); - System.out.println(linkedList); - System.out.println(linkedList.removeFront()); - System.out.println(linkedList); - - System.out.println(linkedList.removeBack()); - System.out.println(linkedList); - System.out.println(linkedList.removeBack()); - System.out.println(linkedList); - - linkedList.remove("Toby"); - System.out.println(linkedList); - -// linkedList.remove((Object) 4); -// System.out.println(linkedList); -// linkedList.remove((Object) 3); -// System.out.println(linkedList); -// linkedList.remove("Howdy"); -// System.out.println(linkedList); -// linkedList.remove((Object) null); -// System.out.println(linkedList); -// linkedList.remove("Howdy"); -// System.out.println(linkedList); - - System.out.println(linkedList.remove(0)); - System.out.println(linkedList); - - - - - - } -} \ No newline at end of file diff --git a/src/interfaces/Deque.java b/src/interfaces/Deque.java deleted file mode 100644 index ccc0916..0000000 --- a/src/interfaces/Deque.java +++ /dev/null @@ -1,45 +0,0 @@ -package interfaces; - -/** - * interfaces.Deque: double-ended queue API - * Supports adding and removing items at both ends. - * - * @param - */ -public interface Deque extends Iterable { - /** - * Checks if the deque is empty. - * @return true if the deque is empty, false otherwise - */ - boolean isEmpty(); - - /** - * Returns the number of items in the deque. - * @return number of items in the deque - */ - int size(); - - /** - * Add an item to the left end of the deque. - * @param item item to be added - */ - void pushLeft(E item); - - /** - * Add an item to the right end of the deque. - * @param item - */ - void pushRight(E item); - - /** - * Remove an item from the left end of the deque. - * @return - */ - E popLeft(); - - /** - * Remove an item from the right end of the deque. - * @return - */ - E popRight(); -} \ No newline at end of file diff --git a/src/interfaces/List.java b/src/interfaces/List.java deleted file mode 100644 index 110869a..0000000 --- a/src/interfaces/List.java +++ /dev/null @@ -1,87 +0,0 @@ -package interfaces; - -/** - * interfaces.List interface (API / abstract data type) - * @param Class or data type of the items in the list. - * @author unknown - * @version 1.0 - */ -public interface List extends Iterable { - /** - * Add item to the front. - * @param item the item to be added - */ - void addFront(E item); - - /** - * Add item to the back. - * @param item the item to be added - */ - void addBack(E item); - - /** - * Add an item at specified index (position). - * @param index the index where the item should be added - * @param item the item to be added - */ - void add(int index, E item); - - /** - * Get the item at a specified index. - * @param index the index where the item should be retrieved - * @return the item located at that index - */ - E get(int index); - - /** - * Set (save) an item at a specified index. Previous - * item at that index is overwritten. - * @param index the index where the item should be saved - * @param item the item to be saved - */ - void set(int index, E item); - - /** - * Remove item at the front of the list. - * @return the item that was removed - */ - E removeFront(); - - /** - * Remove item at the back of the list - * @return the item that was removed - */ - E removeBack(); - - /** - * Remove item from the list - * @param item the item to be removed - */ - void remove(E item); - - /** - * Remove item at a specified index. - * @param index the index where the item should be removed - * @return the item that was removed - */ - E remove(int index); - - /** - * 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 - */ - boolean contains(E item); - - /** - * Checks if the list is empty. - * @return true if the list is empty, false otherwise - */ - boolean isEmpty(); - - /** - * Provides a count of the number of items in the list. - * @return number of items in the list - */ - int size(); -} diff --git a/src/interfaces/MathSet.java b/src/interfaces/MathSet.java deleted file mode 100644 index b8ca20d..0000000 --- a/src/interfaces/MathSet.java +++ /dev/null @@ -1,105 +0,0 @@ -package interfaces; - -/** - * interfaces.MathSet API (interface / abstract data type) - * represents a mathematical set. Sets in mathematics - * have unique elements (keys) and there are no duplicate keys. - * - * In this interfaces.MathSet API, we have an additional constraint that - * traditional mathematical sets do not have. In mathematical sets, - * elements are unordered, order of keys does not matter. In this - * interfaces.MathSet API, we require items to be Comparable so we can maintain - * them in order. By keeping items in order, we can guarantee - * some reasonable performance for the set operations (union, - * intersection, difference, symmetric difference) and for search - * (contains). - * - * @param class/data type of the keys or elements in the set - */ -public interface MathSet extends Iterable { - /** - * Adds a key (item) to the set. Duplicate items - * are not added. - * @param key the key (item) to be added - */ - void add(E key); - - /** - * Removes a key (item) from the set. - * @param key the key (item) to be removed - */ - void remove(E key); - - /** - * Checks if a key (item) is an element in the set. - * @param key the key (item) to check - * @return true if the key is in the set, false otherise - */ - boolean contains(E key); - - /** - * Checks if this set is equal to another set. - * @param other the set to compare this set against - * @return true if this set is equal to the other set - */ - boolean equals(MathSet other); - - /** - * Checks if this set is a subset of another set. - * @param other the set to compare this set against - * @return true if this set is a subset of the other set - */ - boolean isSubsetOf(MathSet other); - - /** - * Checks if this set is a proper subset of another set. - * @param other the set to compare this set against - * @return true if this set is a proper subset of the other set - */ - boolean isProperSubsetOf(MathSet other); - - /** - * Computes the union of this set and another specified set. - * Does not change the contents of this set. - * @param other the second set for the operation - * @return new interfaces.MathSet that contains the union - */ - MathSet union(MathSet other); - - /** - * Computes the intersection of this set and another specified set. - * Does not change the contents of this set. - * @param other the second set for the operation - * @return new interfaces.MathSet that contains the intersection - */ - MathSet intersection(MathSet other); - - /** - * Computes the difference of this set and another specified set. - * Does not change the contents of this set. - * @param other the second set for the operation - * @return new interfaces.MathSet that contains the difference - */ - MathSet difference(MathSet other); - - /** - * Computes the symmetric difference of this set and another specified set. - * Does not change the contents of this set. - * @param other the second set for the operation - * @return new interfaces.MathSet that contains the symmetric difference - */ - MathSet symmetricDifference(MathSet other); - - /** - * Checks if this set is empty. - * @return true if this set is empty, false otherwise - */ - boolean isEmpty(); - - /** - * Returns a count of the number of keys (elements) in this set - * also known as the cardinality of the set. - * @return number of keys (elements) in this set. - */ - int size(); -} diff --git a/src/interfaces/Queue.java b/src/interfaces/Queue.java deleted file mode 100644 index bceaf58..0000000 --- a/src/interfaces/Queue.java +++ /dev/null @@ -1,31 +0,0 @@ -package interfaces; - -/** - * FIFO (first-in, first-out) interfaces.Queue API - * @param class / data type of the items in the queue - */ -public interface Queue extends Iterable { - /** - * Add an item to the queue. - * @param item the item to be added - */ - void enqueue(E item); - - /** - * Remove an item from the queue. - * @return the item that was removed - */ - E dequeue(); - - /** - * Checks to see if the queue is empty. - * @return true if the queue is empty, false otherwise - */ - boolean isEmpty(); - - /** - * Returns a count of the number of items in the queue. - * @return the number of items in the queue - */ - int size(); -} diff --git a/src/interfaces/Stack.java b/src/interfaces/Stack.java deleted file mode 100644 index f6ddac7..0000000 --- a/src/interfaces/Stack.java +++ /dev/null @@ -1,38 +0,0 @@ -package interfaces; - -/** - * interfaces.Stack (LIFO: last-in, first-out) API - * @param class / data type of the items in the stack - */ -public interface Stack extends Iterable { - /** - * Add an item to the stack. - * @param item the item to be added - */ - void push(E item); - - /** - * Removes the most recently added item from the stack. - * @return the item that was removed - */ - E pop(); - - /** - * 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. - */ - E peek(); - - /** - * Checks to see if the stack is empty. - * @return true if the stack is empty, false otherwise - */ - boolean isEmpty(); - - /** - * Returns a count of the number of items in the stack. - * @return the number of items in the stack - */ - int size(); -} diff --git a/tests/ArrayListTest.java b/tests/ArrayListTest.java new file mode 100644 index 0000000..ce92af2 --- /dev/null +++ b/tests/ArrayListTest.java @@ -0,0 +1,337 @@ +package tests; + + import abstractDataTypes.ArrayList; + import interfaces.List; + import org.junit.jupiter.api.Test; + + import static org.junit.jupiter.api.Assertions.assertThrows; + +/** + * Test Class for ArrayIntList + * @author tobygoetz + * @version 1.0 + */ +public class ArrayListTest { + public List empty = new ArrayList<>(new String[]{}); + public List nearlyEmpty = new ArrayList<>(new String[]{"Toby"}); + public List notEmpty = new ArrayList<>(new String[]{"Toby", "is", "cool", "!" }); + public List full = new ArrayList<>(new String[] + {"Toby", "is", "cool", "!", " ", "Or", "so", "he", "belives", "!" }); + + public Exception exception; + public static final int ITERATIONS = 15; + + /** + * Test adds Integer values to the front when empty, almost empty, + * not empty and when buffer is larger than intial size of 10 is + * surpassed. + */ +// @Test +// public void addFrontTest() { +// assertEquals(0, array.size()); +// for (int i = 0; i <= ITERATIONS; i++) { +// array.addFront(i); +// // Index 0 changes everytime addFront is called +// assertEquals(i, array.get(0)); +// } +// } +// +// /** +// * Test adds Integer values to the back when empty, almost empty, +// * not empty and when buffer is larger than intial size of 10 is +// * surpassed. +// */ +// @Test +// public void addBackTest() { +// array.clear(); +// assertEquals(0, array.size()); +// for (int i = 0; i <= ITERATIONS; i++) { +// array.addBack(i); +// // Index 0 changes everytime addFront is called +// assertEquals(i, array.get(array.size() - 1)); +// } +// } +// +// /** +// * Test adds Integer values at specific index when empty, almost +// * empty,not empty and when buffer is larger than intial size of +// * 10 is surpassed. +// */ +// @Test +// public void addTest() { +// array.clear(); +// assertEquals(0, array.size()); +// for (int i = 0; i <= ITERATIONS; i++) { +// array.add(i, i); +// // Index at i incrementing +// assertEquals(i, array.get(i)); +// } +// +// for (int i = ITERATIONS; i >= 0; i--) { +// array.add(i, i); +// // Index at i decrementing +// assertEquals(i, array.get(i)); +// } +// +// //IndexOutOfBoundsException is thrown if -1 is called +// exception = assertThrows( +// IndexOutOfBoundsException.class, () -> { +// array.add(-1, ITERATIONS); +// }); +// +// //IndexOutOfBoundsException is thrown if index larger than +// // the amount of indices is called +// exception = assertThrows( +// IndexOutOfBoundsException.class, () -> { +// array.add(array.size() + 1, ITERATIONS); +// }); +// } +// +// /** +// * Test removes Integer values from the front of ArrayIntList when +// * empty, almost empty and not empty +// */ +// @Test +// public void removeFrontTest() { +// array.clear(); +// assertEquals(0, array.size()); +// +// //test with empty array +// array.removeFront(); +// exception = assertThrows( +// IndexOutOfBoundsException.class, () -> { +// array.get(0); +// }); +// assertTrue(array.isEmpty()); +// +// //test with 1 value in array +// array.addFront(ITERATIONS); +// array.removeFront(); +// assertTrue(array.isEmpty()); +// +// for (int i = 0; i <= ITERATIONS; i++) { +// array.add(i, i); +// } +// for (int i = 0; i < ITERATIONS; i++) { +// int removedValue = array.get(1); +// array.removeFront(); +// assertEquals(removedValue, array.get(0)); +// } +// } +// +// /** +// * Test removes Integer values from the front of ArrayIntList when +// * empty, almost empty and not empty +// */ +// @Test +// public void removeBackTest() { +// array.clear(); +// assertEquals(0, array.size()); +// +// //test with empty array +// array.removeBack(); +// exception = assertThrows( +// IndexOutOfBoundsException.class, () -> { +// array.get(0); +// }); +// assertTrue(array.isEmpty()); +// +// //test with 1 value in array +// array.addFront(ITERATIONS); +// array.removeBack(); +// assertTrue(array.isEmpty()); +// +// //Finish this for removed +//// for (int i = 0; i <= ITERATIONS; i++) { +//// array.add(i, i); +//// } +//// for (int i = 0; i < ITERATIONS; i++) { +//// int removedValue = array.get(1); +//// array.removeFront(); +//// assertEquals(removedValue, array.get(0)); +//// } +// } +// +// /** +// * Test removes Integer values at specific index when empty, almost +// * empty,not empty and when buffer is larger than intial size of +// * 10 is surpassed. +// */ +// @Test +// public void removeTest() { +// array.clear(); +// assertEquals(0, array.size()); +// +// //test with empty array +// exception = assertThrows( +// IndexOutOfBoundsException.class, () -> { +// array.get(0); +// }); +// assertTrue(array.isEmpty()); +// +// //test with index higher than size of array +// exception = assertThrows( +// IndexOutOfBoundsException.class, () -> { +// array.get(array.size()); +// }); +// assertTrue(array.isEmpty()); +// +// //test with one value in array +// array.addFront(0); +// array.remove(0); +// assertTrue(array.isEmpty()); +// assertEquals(0, array.size()); +// +// for (int i = 0; i <= ITERATIONS; i++) { +// array.add(i, i); +// } +// for (int i = 0; i < ITERATIONS; i++) { +// int removedValue = array.get(1); +// array.remove(0); +// assertEquals(removedValue, array.get(0)); +// } +// } +// +// /** +// * Test get method returns for empty, almost empty +// * and exception throw due to Index out of bounds +// */ +// @Test +// public void getTest() { +// array.clear(); +// assertEquals(0, array.size()); +// +// //test with empty array +// exception = assertThrows( +// IndexOutOfBoundsException.class, () -> { +// array.get(0); +// }); +// assertTrue(array.isEmpty()); +// +// //test with index greater than size of array +// //test with empty array +// exception = assertThrows( +// IndexOutOfBoundsException.class, () -> { +// array.get(1); +// }); +// assertTrue(array.isEmpty()); +// +// //reassign values +// this.fillArray(array); +// +// //test the return values of get() +// for (int i = 0; i <= ITERATIONS; i++) { +// int getValue = array.get(i); +// assertEquals(getValue, array.get(i)); +// } +// } +// +// /** +// * Test contains() for non-existent values, existing values, +// * against empty list +// */ +// @Test +// public void containsTest() { +// array.clear(); +// assertEquals(0, array.size()); +// +// //Test if empty +// assertFalse(array.contains(ITERATIONS)); +// +// //Test if value 1 exists +// array.add(0, 1); +// assertTrue(array.contains(1)); +// +// //test if Iterations exists +// this.fillArray(array); +// assertTrue(array.contains(ITERATIONS)); +// +// //test if number does not exist +// assertFalse(array.contains(80085)); +// } +// +// /** +// * Test IndexOf() for no values, some values, +// * against empty list +// */ +// @Test +// public void IndexOfTest() { +// //saftey check +// array.clear(); +// assertEquals(0, array.size()); +// +// //test bounds of IndexOf() +// assertEquals(-1, array.indexOf(-ITERATIONS)); +// +// //test if indices match value returns of all indices +// System.out.println(array); +// for (int i = 0; i < ITERATIONS; i++) { +// array.addBack(i); +// } +// for (int i = 0; i < ITERATIONS; i++) { +// array.addBack(i); +// assertEquals(i, array.indexOf(i)); +// } +// } +// +// /** +// * Test isEmpty() for no values, some values, +// * against empty list +// */ +// @Test +// public void isEmptyTest() { +// //saftey check +// array.clear(); +// assertEquals(0, array.size()); +// +// //test against non-empty array +// this.fillArray(array); +// assertFalse(array.isEmpty()); +// } +// +// /** +// * Test size() for no values, some values, +// * against empty list +// */ +// @Test +// public void sizeTest() { +// //saftey check +// array.clear(); +// assertEquals(0, array.size()); +// +// //test against non-empty array +// for (int i = 0; i < ITERATIONS; i++) { +// array.addBack(i); +// assertEquals(i + 1, array.size()); +// } +// } +// +// /** +// * Test clear() for no values, some values, +// * against empty list +// */ +// @Test +// public void clearTest() { +// //saftey check +// array.clear(); +// assertEquals(0, array.size()); +// +// //test against non-empty array +// this.fillArray(array); +// array.clear(); +// assertEquals(0, array.size()); +// } +// +// /** +// * Helper method to fill the array in this class +// * @param arr Field array +// */ +// public void fillArray(ArrayIntList arr) { +// //reassign values +// for (int i = 0; i <= ITERATIONS; i++) { +// array.addFront(i); +// // Index 0 changes everytime addFront is called +// assertEquals(i, array.get(0)); +// } +// } +} From 81a0f03ff33a70fd8eca92aac089926094aeee97 Mon Sep 17 00:00:00 2001 From: tobygoetz Date: Tue, 13 Feb 2024 11:19:02 -0800 Subject: [PATCH 08/10] Added ArrayListTest and restructured package --- src/abstractDataTypes/ArrayList.java | 462 ++++++++++++++++++++++++++ src/abstractDataTypes/LinkedList.java | 427 ++++++++++++++++++++++++ src/driver/Main.java | 165 +++++++++ src/interfaces/Deque.java | 45 +++ src/interfaces/List.java | 91 +++++ src/interfaces/MathSet.java | 105 ++++++ src/interfaces/Queue.java | 31 ++ src/interfaces/Stack.java | 38 +++ src/tests/ArrayListTest.java | 334 +++++++++++++++++++ tests/ArrayListTest.java | 27 +- 10 files changed, 1708 insertions(+), 17 deletions(-) create mode 100644 src/abstractDataTypes/ArrayList.java create mode 100644 src/abstractDataTypes/LinkedList.java create mode 100644 src/driver/Main.java create mode 100644 src/interfaces/Deque.java create mode 100644 src/interfaces/List.java create mode 100644 src/interfaces/MathSet.java create mode 100644 src/interfaces/Queue.java create mode 100644 src/interfaces/Stack.java create mode 100644 src/tests/ArrayListTest.java diff --git a/src/abstractDataTypes/ArrayList.java b/src/abstractDataTypes/ArrayList.java new file mode 100644 index 0000000..4ae5ae7 --- /dev/null +++ b/src/abstractDataTypes/ArrayList.java @@ -0,0 +1,462 @@ +package abstractDataTypes; + +import interfaces.List; + +import java.util.Arrays; +import java.util.Iterator; +import java.util.NoSuchElementException; + +/** + * @author tobygoetz + * @version 1.0 + * Generic ArrayList, to be used with any data type + * @param specifies data type to be used in ArrayList + */ +public class ArrayList implements List { + + private static final int CAPACITY = 10; + + // fields + private E[] buffer; + private int size; + + /** + * Constructor for ArrayList + */ + public ArrayList() + { + size = 0; + buffer = (E[]) new Object[CAPACITY]; + } + + /** + * Constructor for ArrayList + * @param array any array type + */ + public ArrayList(E[] array) + { + size = 0; + buffer = array; + } + + + /** + * Add item to the front. + * (7(size) + 3) + (5(BL) + 6) == 15(size) + 9 at worst + * 7(size) + 3 at best + * 0(size) + * This function is linear because it reassigns all values to the + * index proceeding it, but calls resize() which is equivalently + * linear as well. + * + * @param item the item to be added + */ + @Override + public void addFront(E item) + { + //loop while index is greater than zero + for (int i = size; i > 0; i--) { // { 1 + 1 + 2 = 4 + //if buffer is at capacity increase buffer by one index + if (size == buffer.length) { // 1 + this.resize(buffer.length + 1); // f(n)= 5BL + 6 + 1 == O(n) + } + //index at highest buffer gets shifted right + buffer[i] = buffer[i - 1]; // 1 + 1 } * size + } + buffer[0] = (E) item; // 1 + size++; // 2 + } // == f(size)= 7(n) + 8(n) + 3 + + /** + * Add item to the back. + * (5BL + 6) + 3 = 5BL + 9 at worst + * f(n) = 2 at best + * This function is constant at best and linear at worst. + * Function is only linear if buffer needs to resize to + * accommodate for 1 additional index + * + * @param item the item to be added + */ + @Override + public void addBack(E item) + { + //if buffer is at capacity increase buffer by one index + if ( size == buffer.length) { + resize(size + 1); + } + //add value to size which is one index greater than last value + buffer[size] = item; + size++; + } + + /** + * Add an item at specified index (position). + * (7 + n)(size - index) + (6 + n) at worst + * O(3 + n) constant at best + * This function is linear at worst because it iterates (size - index) times + * and constant at best when invalid index throws exception which I am + * assuming is a constant constructor call. + * + * @param index the index where the item should be added + * @param item the item to be added + */ + @Override + public void add(int index, E item) + { + if (index < 0 || index > size) { // 3 + throw new IndexOutOfBoundsException("Specified Index Must Be " + // + n + "In the Range of 0-" + size); + } else { + //loop while index is greater than index value specified + for (int i = size; i >= index; i--) { // { 4 + //if buffer is at capacity increase buffer by one index + if (size == buffer.length) { // 1 + this.resize(buffer.length + 1); // 5BL + 6 + } + //index at highest buffer gets shifted right + if (i != 0) { // 1 + buffer[i] = buffer[i - 1]; // 1 } * (size - index) + } // == (7 + n)(size - index) + (6 + n) + } + } + buffer[index] = item; // 1 + size++; // 2 + } + + /** + * Get the item at a specified index. + * O(2 + n) at worst + * O(3) at best + * This function is linear across assuming that + * thrown exception is a relative linear constructor call and + * accounting for branches (I presume) + * + * @param index the index where the item should be retrieved + * @return the item located at that index + */ + @Override + public E get(int index) + { + if (index < 0 ) { // 1 + throw new IndexOutOfBoundsException( // n + "Index must be greater than 0"); + } else if (index >= size ) { // 1 + if (size == 0) { // 1 + throw new IndexOutOfBoundsException( // n + "This list is empty"); + } else { + throw new IndexOutOfBoundsException( // n + "Specified Index Must Be " + + "In the Range of 0-" + (size - 1)); // 1 + } + } return buffer[index]; // 1 + } + + /** + * Set (save) an item at a specified index. Previous + * item at that index is overwritten. + * O(3 + 1) at best + * O(4 + n) at worst + * This function is constant'ish but still technically linear + * because if O(3) = O(3 * n), then n = 1. Boom math... + * I want to say constant because I know a fixed amount at worst + * and at best, but not as constant as size() + * + * @param index the index where the item should be saved + * @param item the item to be saved + */ + @Override + public void set(int index, E item) + { + if (index < 0 || index >= size) { // 3 + throw new IndexOutOfBoundsException("Specified Index Must Be " + // n + "In the Range of 0-" + (size - 1)); // 1 + } else { + buffer[index] = item; // 1 + } + } + + /** + * Remove item at the front of the list. + * (6(size - 2) + 8) + ((5BL + 6) +2) + * O(BL) at worst + * O(size - 2) at best if buffer does not need to resize + * This function is linear because it iterates over entire + * array and possibly again through resize() + * + * @return the item that was removed + */ + @Override + public E removeFront() + { + if (!isEmpty()) { // 1 + O(3) + E removed = buffer[0]; // 1 + for (int i = 0; i <= size - 2; i++) { // { 4 + buffer[i] = buffer[i + 1]; // 1 + 1 } * (size - 2) + } size--; // 2 + + //Reduce buffer until original buffer size is reached + if (size >= 10) { // 1 + resize(size); // 5BL + 6 + //after buffer becomes 10 set removed values back to null + } else { + buffer[size] = null; // 1 + } + return removed; + } else { + return null; + } + } + + /** + * Remove item at the back of the list + * O(1) at best?? + * O(9) at worst + * Constant at best because return null is an assignment'ish + * + * @return the item that was removed + */ + @Override + public E removeBack() + { + if (!isEmpty()) { // O(3) + E removed = buffer[size - 1]; // 1 + 1 + buffer[size - 1] = null; // 1 + 1 + size--; // 2 + return removed; + } else { + return null; + } + } + + /** + * Remove item from the list + * (3 + BL) or O(12) or (11(size - 1) + 3) + 3 + O(size) + 5BL + 6) + * so 0(2n) at worst + * This function could definitely been written cleaner but in Britain + * they have phrase 'any road' meaning you'll always get there as long + * as you keep driving... My logic took a binary search approach to finding + * the answer, but instead of analyzing one or the other I analyzed both. + * + * @param item the item to be removed + */ + @Override + public void remove(E item) + { + if (this.contains(item)) { // 0(size) + if (this.buffer[0].equals(item)) { // 1array access + 1 conditional + this.removeFront(); // 0(BL) + } else if (this.buffer[size - 1].equals(item)) { // 1 + 1 + 1 + this.removeBack(); // 0(9) + } else { + int index = 0; // 1 + while (!buffer[index].equals(item)) { // { 1 + 1 + index++; // 1 + 1 } * (BL - B[i]) + } + for (int i = index; i < size - 1; i++) { // { 4 + buffer[i] = buffer[i + 1]; // 1 + 1 } * size - 1 + } + size--; // 2 + if (size >= 10) { // 1 + resize(size); // 5BL + 6 + //after buffer becomes 10 set removed values back to null + } else { + buffer[size] = null; // 1 + 1 + } + } + } + } + + /** + * Remove item at a specified index. + * (((8(size -1) + 4) + 2) + 2) + 1) + * O(size - 1) at worst + * O(2) at best + * Almost constant on invalid input but linear if removing any index + * but the index at the back of array, I think I accounted for branching + * in this one. My assumption is don't include unreachable code in + * the calculation of the y-axis, but probably the conditionals themselves. + * + * @param index the index where the item should be removed + * @return the item that was removed + */ + @Override + public E remove(int index) + { + // first, check the index to see if it is valid + if (index < 0) { // 1 + throw new IndexOutOfBoundsException("Index cannot be negative"); // 1 + } else if (index >= size) { // 1 + throw new IndexOutOfBoundsException("Index is higher than size"); // 1 + } + + // save a copy of the value to be removed so that we can return it later + E copyOfRemovedValue = buffer[index]; // 1 + 1 + + // if index is last index with valid data, set data to null + if (index == size - 1) { // 1 + 1 + buffer[index] = null; // 1 + 1 + // shift all values over starting at index to be removed + } else { // { 4 + for (int i = index; i < size - 1; i++) { // 1 + 1 + 1 + 1 } * (size - 1) + buffer[i] = buffer[i + 1]; + } + } size--; // 2 + // set trailing index to null to account for reduced size + buffer[size] = null; // 1 + 1 + + return copyOfRemovedValue; // 1 + } + + /** + * Checks if an item is in the list. + * O(size) at worst + * O(1) at best + * This function is linear but constant in the case that an + * array is empty + * + * @param item the item to search for + * @return true if the item is in the list, false otherwise + */ + @Override + public boolean contains(Object item) + { + int index = 0; // 1 + while (index != size) { // { 1 + if (buffer[index].equals(item)) { // 1 + 1 + return true; // 1 + } else { + index++; // 1 + 1 } * size + } + } return false; // 1 + } + + /** + * Checks if the list is empty. + * 0(3) at best and worst + * This method is constant and will always be constant'ish + * but linear for all intents and purposes + * + * @return true if the list is empty, false otherwise + */ + @Override + public boolean isEmpty() { + return size == 0 && buffer[0] == null; // 3 + } + + /** + * Provides a count of the number of items in the list. + * O(1) at best and worst + * Doesn't get much better than this + * + * @return number of items in the list + */ + @Override + public int size() { + return size; // 1 + } + + /** + * Returns an iterator over elements of type {@code T}. + * O(2) at best?? + * I wouldn't know if the constructor is this.iterator = iterator + * because it's implicit and can't remember nor find how to look + * up imported static function calls in intellij + * + * @return an Iterator. + */ + @Override + public Iterator iterator() { + return new ArrayListIterator(); // 1 + 1'ish + } + + private class ArrayListIterator implements Iterator { + + private int index; + + private ArrayListIterator() { index = 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 index < 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 (index >= size) { + throw new NoSuchElementException("Index is out of range"); + } + + E currentValue = buffer[index]; + index++; + return currentValue; + } + } + + /** + * Helper method to resize ArrayIntlist to support + * more data + * f(BL) = 5BL + 6 + * O(n) at worst and at best + * This function is linear at worst because it loops over all existing + * indices in the buffer and still linear but insignificantly faster + * if new buffer is less than existing buffer + */ + private void resize(int newSize) { + //create new space, separate from the old space (buffer) +// int newSize = size + CAPACITY; + E[] newBuffer = (E[]) new Object[newSize]; // 1 + 3 (Assuming that new object is constant) + + // copy everything over from buffer into newBuffer + if (newSize > buffer.length) { // 1 + for (int i = 0; i < buffer.length; i++) { // { 1 + 1 + 2 (i = i + 1) * BL + newBuffer[i] = buffer[i]; // 1 } == 5BL + 6 + } // + } else { // + for (int i = 0; i < newBuffer.length; i++) { // { 1 + 1 + 2 * NBL + newBuffer[i] = buffer[i]; // 1 } == 5BL + 6 + } // + } + + // set the new space into buffer + buffer = newBuffer; // 1 + + // the old space is no longer "pointed to" and will eventually + // be cleaned up by the garbage collector + } + + /** + * If I remember right Strings are objects which are arrays of characters, + * thus a new String = an iteration over an array to build that string. + * So that being, each new String here is actually 0(String.length) + + * operands + static method call to toString which probably iterates again... + * O(bigNumber * character) + few operands + * 0(n) at worst... + * + * @return String representation of ArrayList + */ + @Override + public String toString() { + return "ArrayList{" + + "size=" + size + + ", indices=" + Arrays.toString(buffer) + + + '}'; + } +} + + + diff --git a/src/abstractDataTypes/LinkedList.java b/src/abstractDataTypes/LinkedList.java new file mode 100644 index 0000000..dddea15 --- /dev/null +++ b/src/abstractDataTypes/LinkedList.java @@ -0,0 +1,427 @@ +package abstractDataTypes; + +import interfaces.List; + +import java.util.Iterator; +import java.util.NoSuchElementException; + +/** + * @author tobygoetz + * @version 1.0 + * + * Generic LinkedList to be used with any data type + * @param + */ +public class LinkedList implements List { + + // Fields + private Node head; + private int size; + + /** + * Constructor to initialize the fields of LinkedIntList + */ + public LinkedList() { + head = null; + size = 0; + } + + // Node Class + private class Node { + private E data; + private Node next; + + /** + * Constuctor for Node that accepts on Integer data + * and sets the next to null + * @param data Integer value of Node + */ + private Node(E data) { + this.data = data; + this.next = null; + } + + /** + * Constuctor for Node that accepts on Integer data + * and sets the next to null + * @param data Integer Value of Node + * @param next Points to the next Node in list + */ + private Node(E data, Node next) { + this.data = data; + this.next = next; + } + + public String toString() { + return data + " -> "; + } + } + + /** + * Add item to the front. + * + * @param item the item to be added + */ + @Override + public void addFront(E item) + { + // new Node to be added + Node addedToFront = new Node(item); + // the list currently has some nodes in it + if (head != null) { + addedToFront.next = head; + } + head = addedToFront; + size++; + } + + /** + * Add item to the back. + * + * @param item the item to be added + */ + @Override + public void addBack(E item) + { + Node addToBack = new Node(item); + + if (head == null) { + head = addToBack; + } else { + Node current = head; + + while (current.next != null) { + current = current.next; + } + current.next = addToBack; + } size++; + } + + /** + * Add an item at specified index (position). + * + * @param index the index where the item should be added + * @param item the item to be added + */ + @Override + public void add(int index, E item) + { + int dex = 1; + //if requested index is out of range throw exception + if (index < 0 || index > (size )) { + throw new IndexOutOfBoundsException( + "Index must be in the Range 0-" + (size)); + //else find Node at index + } else { + //check if index is head + if (index == 0) { + addFront(item); + //check if index is at the end + } else if (index == (size)) { + addBack(item); + //remove everywhere else + } else { + Node current = head; + while (dex <= index - 1) { + current = current.next; + dex++; + } + current.next = new Node(item, current.next); + size++; + } + } + } + + /** + * Get the item at a specified index. + * + * @param index the index where the item should be retrieved + * @return the item located at that index + */ + @Override + public E get(int index) + { + int dex = 1; + + //if requested index is out of range throw exception + if (index < 0 || index > (size - 1)) { + throw new IndexOutOfBoundsException( + "Index must be in the Range 0-" + (size - 1)); + //else find Node at index + } else { + //head is always at index 0 + if (index == 0) { + return head.data; + } else { + Node current = head; + while(dex <= index) { + current = current.next; + dex++; + } + return current.data; + } + } + } + + /** + * Set (save) an item at a specified index. Previous + * item at that index is overwritten. + * + * @param index the index where the item should be saved + * @param item the item to be saved + */ + @Override + public void set(int index, E item) + { + if (index < 0 || index >= size) { + throw new IndexOutOfBoundsException("Specified Index Must Be " + + "In the Range of 0-" + (size - 1)); + } else { + Node newNode = new Node(item); + Node current = head; + + if (index == 0) { + if (head != null) { + newNode.next = head.next; + } head = newNode; + + } else if (index == (size - 1)) { + while (current.next.next != null) { + current = current.next; + } current.next = newNode; + + } else { + for (int i = 1; i < index; i++) { + current = current.next; + } + newNode.next = current.next.next; + current.next = newNode; + } + } + } + + /** + * Remove item at the front of the list. + * + * @return the item that was removed + */ + @Override + public E removeFront() + { + if (head != null) { + E removedData = head.data; + if (head.next != null) { + head = head.next; + } else { + head = null; + } + size--; + return removedData; + } return null; + } + + /** + * Remove item at the back of the list + * + * @return the item that was removed + */ + @Override + public E removeBack() + { + if (head != null) { + Node current = head; + + if (current.next != null) { + while (current.next.next != null) { + current = current.next; + } + E removedData = current.next.data; + current.next = null; + size--; + return removedData; + } else { + E removedData = head.data; + head = null; + size = 0; + return removedData; + } + } return null; + } + + /** + * Remove item from the list + * + * @param item the item to be removed + */ + @Override + public void remove(E item) + { + if (this.contains(item)) { + Node current = head; + if (head.data.equals(item)) { + removeFront(); + } else { + while (!current.next.data.equals(item)) { + current = current.next; + } + current.next = current.next.next; + size--; + } + } + } + + /** + * Remove item at a specified index. + * + * @param index the index where the item should be removed + * @return the item that was removed + */ + @Override + public E remove(int index) + { + int dex = 1; + E removedData; + + //if requested index is out of range throw exception + if (index < 0 || index > (size - 1)) { + throw new IndexOutOfBoundsException( + "Index must be in the Range 0-" + (size - 1)); + } else { + //check if index is head + if (index == 0) { + removedData = head.data; + removeFront(); + } else { + Node current = head; + while (dex <= index - 1) { + current = current.next; + dex++; + } + removedData = current.next.data; + current.next = current.next.next; + size--; + } + return removedData; + } + } + + /** + * 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) + { + if (head != null) { + Node current = head; + if (current.data.equals(item)) { + return true; + } else { + while (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(); + } + + private class LinkedListIterator implements Iterator { + + private Node current; + + 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 + */ + @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 (current == null) { + throw new NoSuchElementException("There is no next one to go to!"); + } + E dataValue = current.data; + current = current.next; + return dataValue; + } + + @Override + public String toString() { + return "LinkedListIterator{" + + "current=" + current + + '}'; + } + } + + + + @Override + public String toString() { + Node current = head; + String list = "LinkedIntList{size=" + size + ", list=["; + + if (current == null) { + list += "]}"; + } else { + while (current != null) { + list += current.data; + if (current.next != null) { + list += ", "; + } else { + list += "]}"; + } + current = current.next; + } + } return list; + } +} diff --git a/src/driver/Main.java b/src/driver/Main.java new file mode 100644 index 0000000..ec895a8 --- /dev/null +++ b/src/driver/Main.java @@ -0,0 +1,165 @@ +package driver; + +import abstractDataTypes.ArrayList; +import abstractDataTypes.LinkedList; + +//TIP To Run code, press or +// click the icon in the gutter. + +/** + * @author tobygoetz + * @version 1.0 + * Driver class to test ArrayList and LinkedList that + * implement list.java + */ +public class Main { + + public static final int ITERATIONS = 25; + + /** + * program to run Main Class + * @param args command line arguments + */ + public static void main(String[] args) { + //TIP Press with your caret at the highlighted text + // to see how IntelliJ IDEA suggests fixing it. + System.out.println("Hello and welcome!"); + +// class Cat { +// private String breed; +// +// public Cat(String breed) { +// this.breed = breed; +// } +// +// @Override +// public String toString() { +// return breed; +// } +// } +// +// String[] breeds = new String[]{ +// "Tabby", "Siamese", "Calico"}; +// +// ArrayList listOfObjects = new ArrayList<>(); +// listOfObjects.addFront(10); +// listOfObjects.addFront("Fresno"); +// listOfObjects.addFront(ITERATIONS); +// listOfObjects.addFront('a'); +// listOfObjects.addFront(new Cat(breeds[1])); +// listOfObjects.addFront(breeds); +// +// System.out.println(listOfObjects); +// +// listOfObjects.addBack(new Cat(breeds[0])); +// listOfObjects.addBack(new Cat(breeds[1])); +// listOfObjects.addBack(new Cat(breeds[0])); +// listOfObjects.addBack(new Cat(breeds[0])); +// listOfObjects.addBack(new Cat(breeds[0])); +// listOfObjects.addBack(new Cat(breeds[0])); +// System.out.println(listOfObjects); +// +// listOfObjects.set(0, 0); +// System.out.println(listOfObjects); +// +// listOfObjects.set((listOfObjects.size() -1), (listOfObjects.size() - 1)); +// listOfObjects.set(0, "front"); +// System.out.println(listOfObjects.size()); +// System.out.println(listOfObjects); +// +// System.out.println(listOfObjects.removeFront()); +// System.out.println(listOfObjects.removeFront()); +// System.out.println(listOfObjects.removeBack()); +// System.out.println(listOfObjects.removeBack()); +// Cat lion = new Cat("Lion"); +// listOfObjects.addFront(lion); +// +// System.out.println(listOfObjects.contains(lion)); +// listOfObjects.removeBack(); +// listOfObjects.removeBack(); +// listOfObjects.removeBack(); +// listOfObjects.removeBack(); +// listOfObjects.removeBack(); +// System.out.println(listOfObjects.contains("Fresn!")); +// +// System.out.println(listOfObjects); +// +// System.out.println(listOfObjects.contains('a')); +// +// System.out.println(); +// System.out.println(listOfObjects); +// listOfObjects.remove((Object) 'a'); +// System.out.println(listOfObjects); +// +// System.out.println(listOfObjects.remove(0)); +// System.out.println(listOfObjects); + + + + + + + // LinkedList Tests + + LinkedList linkedList = new LinkedList<>(); + + linkedList.addFront("Toby"); + linkedList.addFront(Math.random()); + linkedList.addFront('%'); + + linkedList.addBack(3); + linkedList.addBack(4); + linkedList.addBack(5); + + linkedList.add(3, "Middle"); + linkedList.add(0, "Front"); + linkedList.add(8, "End"); + + System.out.println(linkedList); + + System.out.println(linkedList.get(3)); + + System.out.println(linkedList.contains(Math.random())); + + System.out.println(linkedList); + + linkedList.set(0, "Tobiah"); + linkedList.set(8, "Howdy"); + linkedList.set(4, "Howdy"); + System.out.println(linkedList); + + System.out.println(linkedList.removeFront()); + System.out.println(linkedList); + System.out.println(linkedList.removeFront()); + System.out.println(linkedList); + System.out.println(linkedList.removeFront()); + System.out.println(linkedList); + + System.out.println(linkedList.removeBack()); + System.out.println(linkedList); + System.out.println(linkedList.removeBack()); + System.out.println(linkedList); + + linkedList.remove("Toby"); + System.out.println(linkedList); + +// linkedList.remove((Object) 4); +// System.out.println(linkedList); +// linkedList.remove((Object) 3); +// System.out.println(linkedList); +// linkedList.remove("Howdy"); +// System.out.println(linkedList); +// linkedList.remove((Object) null); +// System.out.println(linkedList); +// linkedList.remove("Howdy"); +// System.out.println(linkedList); + + System.out.println(linkedList.remove(0)); + System.out.println(linkedList); + + + + + + } +} \ No newline at end of file diff --git a/src/interfaces/Deque.java b/src/interfaces/Deque.java new file mode 100644 index 0000000..ccc0916 --- /dev/null +++ b/src/interfaces/Deque.java @@ -0,0 +1,45 @@ +package interfaces; + +/** + * interfaces.Deque: double-ended queue API + * Supports adding and removing items at both ends. + * + * @param + */ +public interface Deque extends Iterable { + /** + * Checks if the deque is empty. + * @return true if the deque is empty, false otherwise + */ + boolean isEmpty(); + + /** + * Returns the number of items in the deque. + * @return number of items in the deque + */ + int size(); + + /** + * Add an item to the left end of the deque. + * @param item item to be added + */ + void pushLeft(E item); + + /** + * Add an item to the right end of the deque. + * @param item + */ + void pushRight(E item); + + /** + * Remove an item from the left end of the deque. + * @return + */ + E popLeft(); + + /** + * Remove an item from the right end of the deque. + * @return + */ + E popRight(); +} \ No newline at end of file diff --git a/src/interfaces/List.java b/src/interfaces/List.java new file mode 100644 index 0000000..87be239 --- /dev/null +++ b/src/interfaces/List.java @@ -0,0 +1,91 @@ +package interfaces; + +import abstractDataTypes.ArrayList; + +/** + * interfaces.List interface (API / abstract data type) + * @param Class or data type of the items in the list. + * @author unknown + * @version 1.0 + */ +public interface List extends Iterable { + /** + * Add item to the front. + * @param item the item to be added + */ + void addFront(E item); + + /** + * Add item to the back. + * @param item the item to be added + */ + void addBack(E item); + + /** + * Add an item at specified index (position). + * @param index the index where the item should be added + * @param item the item to be added + */ + void add(int index, E item); + + /** + * Get the item at a specified index. + * @param index the index where the item should be retrieved + * @return the item located at that index + */ + E get(int index); + + /** + * Set (save) an item at a specified index. Previous + * item at that index is overwritten. + * @param index the index where the item should be saved + * @param item the item to be saved + */ + void set(int index, E item); + + /** + * Remove item at the front of the list. + * @return the item that was removed + */ + E removeFront(); + + /** + * Remove item at the back of the list + * @return the item that was removed + */ + E removeBack(); + + /** + * Remove item from the list + * @param item the item to be removed + */ + void remove(E item); + + /** + * Remove item at a specified index. + * @param index the index where the item should be removed + * @return the item that was removed + */ + E remove(int index); + + /** + * 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 + */ + boolean contains(E item); + + /** + * Checks if the list is empty. + * @return true if the list is empty, false otherwise + */ + boolean isEmpty(); + + /** + * Provides a count of the number of items in the list. + * @return number of items in the list + */ + int size(); +} + + diff --git a/src/interfaces/MathSet.java b/src/interfaces/MathSet.java new file mode 100644 index 0000000..b8ca20d --- /dev/null +++ b/src/interfaces/MathSet.java @@ -0,0 +1,105 @@ +package interfaces; + +/** + * interfaces.MathSet API (interface / abstract data type) + * represents a mathematical set. Sets in mathematics + * have unique elements (keys) and there are no duplicate keys. + * + * In this interfaces.MathSet API, we have an additional constraint that + * traditional mathematical sets do not have. In mathematical sets, + * elements are unordered, order of keys does not matter. In this + * interfaces.MathSet API, we require items to be Comparable so we can maintain + * them in order. By keeping items in order, we can guarantee + * some reasonable performance for the set operations (union, + * intersection, difference, symmetric difference) and for search + * (contains). + * + * @param class/data type of the keys or elements in the set + */ +public interface MathSet extends Iterable { + /** + * Adds a key (item) to the set. Duplicate items + * are not added. + * @param key the key (item) to be added + */ + void add(E key); + + /** + * Removes a key (item) from the set. + * @param key the key (item) to be removed + */ + void remove(E key); + + /** + * Checks if a key (item) is an element in the set. + * @param key the key (item) to check + * @return true if the key is in the set, false otherise + */ + boolean contains(E key); + + /** + * Checks if this set is equal to another set. + * @param other the set to compare this set against + * @return true if this set is equal to the other set + */ + boolean equals(MathSet other); + + /** + * Checks if this set is a subset of another set. + * @param other the set to compare this set against + * @return true if this set is a subset of the other set + */ + boolean isSubsetOf(MathSet other); + + /** + * Checks if this set is a proper subset of another set. + * @param other the set to compare this set against + * @return true if this set is a proper subset of the other set + */ + boolean isProperSubsetOf(MathSet other); + + /** + * Computes the union of this set and another specified set. + * Does not change the contents of this set. + * @param other the second set for the operation + * @return new interfaces.MathSet that contains the union + */ + MathSet union(MathSet other); + + /** + * Computes the intersection of this set and another specified set. + * Does not change the contents of this set. + * @param other the second set for the operation + * @return new interfaces.MathSet that contains the intersection + */ + MathSet intersection(MathSet other); + + /** + * Computes the difference of this set and another specified set. + * Does not change the contents of this set. + * @param other the second set for the operation + * @return new interfaces.MathSet that contains the difference + */ + MathSet difference(MathSet other); + + /** + * Computes the symmetric difference of this set and another specified set. + * Does not change the contents of this set. + * @param other the second set for the operation + * @return new interfaces.MathSet that contains the symmetric difference + */ + MathSet symmetricDifference(MathSet other); + + /** + * Checks if this set is empty. + * @return true if this set is empty, false otherwise + */ + boolean isEmpty(); + + /** + * Returns a count of the number of keys (elements) in this set + * also known as the cardinality of the set. + * @return number of keys (elements) in this set. + */ + int size(); +} diff --git a/src/interfaces/Queue.java b/src/interfaces/Queue.java new file mode 100644 index 0000000..bceaf58 --- /dev/null +++ b/src/interfaces/Queue.java @@ -0,0 +1,31 @@ +package interfaces; + +/** + * FIFO (first-in, first-out) interfaces.Queue API + * @param class / data type of the items in the queue + */ +public interface Queue extends Iterable { + /** + * Add an item to the queue. + * @param item the item to be added + */ + void enqueue(E item); + + /** + * Remove an item from the queue. + * @return the item that was removed + */ + E dequeue(); + + /** + * Checks to see if the queue is empty. + * @return true if the queue is empty, false otherwise + */ + boolean isEmpty(); + + /** + * Returns a count of the number of items in the queue. + * @return the number of items in the queue + */ + int size(); +} diff --git a/src/interfaces/Stack.java b/src/interfaces/Stack.java new file mode 100644 index 0000000..f6ddac7 --- /dev/null +++ b/src/interfaces/Stack.java @@ -0,0 +1,38 @@ +package interfaces; + +/** + * interfaces.Stack (LIFO: last-in, first-out) API + * @param class / data type of the items in the stack + */ +public interface Stack extends Iterable { + /** + * Add an item to the stack. + * @param item the item to be added + */ + void push(E item); + + /** + * Removes the most recently added item from the stack. + * @return the item that was removed + */ + E pop(); + + /** + * 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. + */ + E peek(); + + /** + * Checks to see if the stack is empty. + * @return true if the stack is empty, false otherwise + */ + boolean isEmpty(); + + /** + * Returns a count of the number of items in the stack. + * @return the number of items in the stack + */ + int size(); +} diff --git a/src/tests/ArrayListTest.java b/src/tests/ArrayListTest.java new file mode 100644 index 0000000..fc431d2 --- /dev/null +++ b/src/tests/ArrayListTest.java @@ -0,0 +1,334 @@ +package tests; + +import abstractDataTypes.ArrayList; +import interfaces.List; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +/** + * Test Class for ArrayIntList + * @author tobygoetz + * @version 1.0 + */ +public class ArrayListTest { + public List empty = new ArrayList<>(new String[]{}); + public List nearlyEmpty = new ArrayList<>(new String[]{"Toby"}); + public List notEmpty = new ArrayList<>(new String[]{"Toby", "is", "cool", "!" }); + public List full = new ArrayList<>(new String[] + {"Toby", "is", "cool", "!", " ", "Or", "so", "he", "belives", "!" }); + + public Exception exception; + public static final int ITERATIONS = 15; + + /** + * Test adds Integer values to the front when empty, almost empty, + * not empty and when buffer is larger than intial size of 10 is + * surpassed. + */ + @Test + public void addFrontTest() { + empty.addFront("BOOM"); + + } + } +// +// /** +// * Test adds Integer values to the back when empty, almost empty, +// * not empty and when buffer is larger than intial size of 10 is +// * surpassed. +// */ +// @Test +// public void addBackTest() { +// array.clear(); +// assertEquals(0, array.size()); +// for (int i = 0; i <= ITERATIONS; i++) { +// array.addBack(i); +// // Index 0 changes everytime addFront is called +// assertEquals(i, array.get(array.size() - 1)); +// } +// } +// +// /** +// * Test adds Integer values at specific index when empty, almost +// * empty,not empty and when buffer is larger than intial size of +// * 10 is surpassed. +// */ +// @Test +// public void addTest() { +// array.clear(); +// assertEquals(0, array.size()); +// for (int i = 0; i <= ITERATIONS; i++) { +// array.add(i, i); +// // Index at i incrementing +// assertEquals(i, array.get(i)); +// } +// +// for (int i = ITERATIONS; i >= 0; i--) { +// array.add(i, i); +// // Index at i decrementing +// assertEquals(i, array.get(i)); +// } +// +// //IndexOutOfBoundsException is thrown if -1 is called +// exception = assertThrows( +// IndexOutOfBoundsException.class, () -> { +// array.add(-1, ITERATIONS); +// }); +// +// //IndexOutOfBoundsException is thrown if index larger than +// // the amount of indices is called +// exception = assertThrows( +// IndexOutOfBoundsException.class, () -> { +// array.add(array.size() + 1, ITERATIONS); +// }); +// } +// +// /** +// * Test removes Integer values from the front of ArrayIntList when +// * empty, almost empty and not empty +// */ +// @Test +// public void removeFrontTest() { +// array.clear(); +// assertEquals(0, array.size()); +// +// //test with empty array +// array.removeFront(); +// exception = assertThrows( +// IndexOutOfBoundsException.class, () -> { +// array.get(0); +// }); +// assertTrue(array.isEmpty()); +// +// //test with 1 value in array +// array.addFront(ITERATIONS); +// array.removeFront(); +// assertTrue(array.isEmpty()); +// +// for (int i = 0; i <= ITERATIONS; i++) { +// array.add(i, i); +// } +// for (int i = 0; i < ITERATIONS; i++) { +// int removedValue = array.get(1); +// array.removeFront(); +// assertEquals(removedValue, array.get(0)); +// } +// } +// +// /** +// * Test removes Integer values from the front of ArrayIntList when +// * empty, almost empty and not empty +// */ +// @Test +// public void removeBackTest() { +// array.clear(); +// assertEquals(0, array.size()); +// +// //test with empty array +// array.removeBack(); +// exception = assertThrows( +// IndexOutOfBoundsException.class, () -> { +// array.get(0); +// }); +// assertTrue(array.isEmpty()); +// +// //test with 1 value in array +// array.addFront(ITERATIONS); +// array.removeBack(); +// assertTrue(array.isEmpty()); +// +// //Finish this for removed +//// for (int i = 0; i <= ITERATIONS; i++) { +//// array.add(i, i); +//// } +//// for (int i = 0; i < ITERATIONS; i++) { +//// int removedValue = array.get(1); +//// array.removeFront(); +//// assertEquals(removedValue, array.get(0)); +//// } +// } +// +// /** +// * Test removes Integer values at specific index when empty, almost +// * empty,not empty and when buffer is larger than intial size of +// * 10 is surpassed. +// */ +// @Test +// public void removeTest() { +// array.clear(); +// assertEquals(0, array.size()); +// +// //test with empty array +// exception = assertThrows( +// IndexOutOfBoundsException.class, () -> { +// array.get(0); +// }); +// assertTrue(array.isEmpty()); +// +// //test with index higher than size of array +// exception = assertThrows( +// IndexOutOfBoundsException.class, () -> { +// array.get(array.size()); +// }); +// assertTrue(array.isEmpty()); +// +// //test with one value in array +// array.addFront(0); +// array.remove(0); +// assertTrue(array.isEmpty()); +// assertEquals(0, array.size()); +// +// for (int i = 0; i <= ITERATIONS; i++) { +// array.add(i, i); +// } +// for (int i = 0; i < ITERATIONS; i++) { +// int removedValue = array.get(1); +// array.remove(0); +// assertEquals(removedValue, array.get(0)); +// } +// } +// +// /** +// * Test get method returns for empty, almost empty +// * and exception throw due to Index out of bounds +// */ +// @Test +// public void getTest() { +// array.clear(); +// assertEquals(0, array.size()); +// +// //test with empty array +// exception = assertThrows( +// IndexOutOfBoundsException.class, () -> { +// array.get(0); +// }); +// assertTrue(array.isEmpty()); +// +// //test with index greater than size of array +// //test with empty array +// exception = assertThrows( +// IndexOutOfBoundsException.class, () -> { +// array.get(1); +// }); +// assertTrue(array.isEmpty()); +// +// //reassign values +// this.fillArray(array); +// +// //test the return values of get() +// for (int i = 0; i <= ITERATIONS; i++) { +// int getValue = array.get(i); +// assertEquals(getValue, array.get(i)); +// } +// } +// +// /** +// * Test contains() for non-existent values, existing values, +// * against empty list +// */ +// @Test +// public void containsTest() { +// array.clear(); +// assertEquals(0, array.size()); +// +// //Test if empty +// assertFalse(array.contains(ITERATIONS)); +// +// //Test if value 1 exists +// array.add(0, 1); +// assertTrue(array.contains(1)); +// +// //test if Iterations exists +// this.fillArray(array); +// assertTrue(array.contains(ITERATIONS)); +// +// //test if number does not exist +// assertFalse(array.contains(80085)); +// } +// +// /** +// * Test IndexOf() for no values, some values, +// * against empty list +// */ +// @Test +// public void IndexOfTest() { +// //saftey check +// array.clear(); +// assertEquals(0, array.size()); +// +// //test bounds of IndexOf() +// assertEquals(-1, array.indexOf(-ITERATIONS)); +// +// //test if indices match value returns of all indices +// System.out.println(array); +// for (int i = 0; i < ITERATIONS; i++) { +// array.addBack(i); +// } +// for (int i = 0; i < ITERATIONS; i++) { +// array.addBack(i); +// assertEquals(i, array.indexOf(i)); +// } +// } +// +// /** +// * Test isEmpty() for no values, some values, +// * against empty list +// */ +// @Test +// public void isEmptyTest() { +// //saftey check +// array.clear(); +// assertEquals(0, array.size()); +// +// //test against non-empty array +// this.fillArray(array); +// assertFalse(array.isEmpty()); +// } +// +// /** +// * Test size() for no values, some values, +// * against empty list +// */ +// @Test +// public void sizeTest() { +// //saftey check +// array.clear(); +// assertEquals(0, array.size()); +// +// //test against non-empty array +// for (int i = 0; i < ITERATIONS; i++) { +// array.addBack(i); +// assertEquals(i + 1, array.size()); +// } +// } +// +// /** +// * Test clear() for no values, some values, +// * against empty list +// */ +// @Test +// public void clearTest() { +// //saftey check +// array.clear(); +// assertEquals(0, array.size()); +// +// //test against non-empty array +// this.fillArray(array); +// array.clear(); +// assertEquals(0, array.size()); +// } +// +// /** +// * Helper method to fill the array in this class +// * @param arr Field array +// */ +// public void fillArray(ArrayIntList arr) { +// //reassign values +// for (int i = 0; i <= ITERATIONS; i++) { +// array.addFront(i); +// // Index 0 changes everytime addFront is called +// assertEquals(i, array.get(0)); +// } +// } + diff --git a/tests/ArrayListTest.java b/tests/ArrayListTest.java index ce92af2..1d91d5e 100644 --- a/tests/ArrayListTest.java +++ b/tests/ArrayListTest.java @@ -1,10 +1,6 @@ -package tests; - - import abstractDataTypes.ArrayList; - import interfaces.List; - import org.junit.jupiter.api.Test; - - import static org.junit.jupiter.api.Assertions.assertThrows; +import abstractDataTypes.ArrayList; +import interfaces.List; +import org.junit.jupiter.api.Test; /** * Test Class for ArrayIntList @@ -26,15 +22,12 @@ public class ArrayListTest { * not empty and when buffer is larger than intial size of 10 is * surpassed. */ -// @Test -// public void addFrontTest() { -// assertEquals(0, array.size()); -// for (int i = 0; i <= ITERATIONS; i++) { -// array.addFront(i); -// // Index 0 changes everytime addFront is called -// assertEquals(i, array.get(0)); -// } -// } + @Test + public void addFrontTest() { + empty.addFront("BOOM"); + + } + } // // /** // * Test adds Integer values to the back when empty, almost empty, @@ -334,4 +327,4 @@ public class ArrayListTest { // assertEquals(i, array.get(0)); // } // } -} + From 80eb14207f8fd5c6b1979cdb5d6ddf89e38200e6 Mon Sep 17 00:00:00 2001 From: tobygoetz Date: Wed, 14 Feb 2024 01:08:20 -0800 Subject: [PATCH 09/10] Ready for review. Added ArrayListTest and LinkedListTest. Finished algorithmic analysis of LinkedList class. --- src/abstractDataTypes/ArrayList.java | 49 +- src/abstractDataTypes/LinkedList.java | 80 +++- src/driver/Main.java | 158 ++++--- src/tests/ArrayListTest.java | 334 -------------- tests/ArrayListTest.java | 614 +++++++++++++------------- tests/LinkedIntListTest.java | 343 ++++++++++++++ 6 files changed, 823 insertions(+), 755 deletions(-) delete mode 100644 src/tests/ArrayListTest.java create mode 100644 tests/LinkedIntListTest.java diff --git a/src/abstractDataTypes/ArrayList.java b/src/abstractDataTypes/ArrayList.java index 4ae5ae7..63aba45 100644 --- a/src/abstractDataTypes/ArrayList.java +++ b/src/abstractDataTypes/ArrayList.java @@ -35,8 +35,15 @@ public ArrayList() */ public ArrayList(E[] array) { - size = 0; - buffer = array; + if (array.length < CAPACITY) { + + E[] newBuffer = (E[]) new Object[CAPACITY]; + + for (int i = 0; i < array.length; i++) { // { 1 + 1 + 2 (i = i + 1) * BL + newBuffer[i] = array[i]; + size++; + } buffer = newBuffer; + } } @@ -54,17 +61,16 @@ public ArrayList(E[] array) @Override public void addFront(E item) { - //loop while index is greater than zero - for (int i = size; i > 0; i--) { // { 1 + 1 + 2 = 4 - //if buffer is at capacity increase buffer by one index - if (size == buffer.length) { // 1 - this.resize(buffer.length + 1); // f(n)= 5BL + 6 + 1 == O(n) - } - //index at highest buffer gets shifted right - buffer[i] = buffer[i - 1]; // 1 + 1 } * size + //if buffer is at capacity increase buffer by one index + if (size == buffer.length) { // 1 + this.resize(buffer.length + 1); // f(n)= 5BL + 6 + 1 == O(n) } - buffer[0] = (E) item; // 1 size++; // 2 + //Move all indices over one to make room at front + for (int i = size - 1; i > 0; i--) { // { 1 + 1 + 2 = 4 + buffer[i] = buffer[i - 1]; // 1 + 1 } * size + } + buffer[0] = item; // 1 } // == f(size)= 7(n) + 8(n) + 3 /** @@ -81,7 +87,7 @@ public void addFront(E item) public void addBack(E item) { //if buffer is at capacity increase buffer by one index - if ( size == buffer.length) { + if (size == buffer.length) { resize(size + 1); } //add value to size which is one index greater than last value @@ -198,7 +204,7 @@ public E removeFront() //Reduce buffer until original buffer size is reached if (size >= 10) { // 1 resize(size); // 5BL + 6 - //after buffer becomes 10 set removed values back to null + // after buffer becomes 10 set removed values back to null } else { buffer[size] = null; // 1 } @@ -234,7 +240,7 @@ public E removeBack() * (3 + BL) or O(12) or (11(size - 1) + 3) + 3 + O(size) + 5BL + 6) * so 0(2n) at worst * This function could definitely been written cleaner but in Britain - * they have phrase 'any road' meaning you'll always get there as long + * they have the phrase 'any road' meaning you'll always get there as long * as you keep driving... My logic took a binary search approach to finding * the answer, but instead of analyzing one or the other I analyzed both. * @@ -358,10 +364,9 @@ public int size() { /** * Returns an iterator over elements of type {@code T}. - * O(2) at best?? - * I wouldn't know if the constructor is this.iterator = iterator - * because it's implicit and can't remember nor find how to look - * up imported static function calls in intellij + * O(n) at best + * O(2^n) at worst + * Depends on how it's used in the client code... * * @return an Iterator. */ @@ -404,6 +409,13 @@ public E next() { index++; return currentValue; } + + @Override + public String toString() { + return "ArrayListIterator{" + + "index=" + index + + '}'; + } } /** @@ -453,7 +465,6 @@ public String toString() { return "ArrayList{" + "size=" + size + ", indices=" + Arrays.toString(buffer) + - '}'; } } diff --git a/src/abstractDataTypes/LinkedList.java b/src/abstractDataTypes/LinkedList.java index dddea15..cd8cdef 100644 --- a/src/abstractDataTypes/LinkedList.java +++ b/src/abstractDataTypes/LinkedList.java @@ -59,6 +59,10 @@ public String toString() { /** * Add item to the front. + * O(5) at best + * O(6) at worst + * This function is Constant because it makes + * a few assignments at most * * @param item the item to be added */ @@ -77,7 +81,11 @@ public void addFront(E item) /** * Add item to the back. - * + * O(5) at best + * O(n) at worst + * This function is Linear because it loops over all + * values in the list, but can be constant in the case + * the list is empty * @param item the item to be added */ @Override @@ -99,6 +107,14 @@ public void addBack(E item) /** * Add an item at specified index (position). + * O(12) at best + * O(n) at worst + * This function is Linear because it loops over all + * values in the list if inserted at back and/or inserted + * in the middle (if inserted in between it iterates + * exactly equal to the index number provided). This + * function can be constant at best if exception are thrown + * or index requested is 0. * * @param index the index where the item should be added * @param item the item to be added @@ -108,7 +124,7 @@ public void add(int index, E item) { int dex = 1; //if requested index is out of range throw exception - if (index < 0 || index > (size )) { + if (index < 0 || index > (size)) { throw new IndexOutOfBoundsException( "Index must be in the Range 0-" + (size)); //else find Node at index @@ -117,7 +133,7 @@ public void add(int index, E item) if (index == 0) { addFront(item); //check if index is at the end - } else if (index == (size)) { + } else if (index == size) { addBack(item); //remove everywhere else } else { @@ -134,6 +150,14 @@ public void add(int index, E item) /** * Get the item at a specified index. + * O(7) at best + * O(n) at worst + * This function is Linear because it loops over all + * values in the list if the index being retrieved is + * at back and/or inserted in the middle (if inserted + * in between it iterates exactly equal to the index + * number provided). This function can be constant at + * best if exception are thrown or index requested is 0. * * @param index the index where the item should be retrieved * @return the item located at that index @@ -166,6 +190,14 @@ public E get(int index) /** * Set (save) an item at a specified index. Previous * item at that index is overwritten. + * O(5) at best + * O(n) + * This function is Linear because it loops over all + * values in the list if the index being set is + * at back and/or towards the middle (if inserted + * in between it iterates exactly equal to the index + * number provided). This function can be constant at + * best if exception are thrown or index requested is 0. * * @param index the index where the item should be saved * @param item the item to be saved @@ -202,6 +234,11 @@ public void set(int index, E item) /** * Remove item at the front of the list. + * O(1) at best + * O(7) at worst + * This function is constant because it is a few + * assignments, but could be O(1) if head is + * being retrieved from an empty list. * * @return the item that was removed */ @@ -222,7 +259,12 @@ public E removeFront() /** * Remove item at the back of the list - * + * O(2) at best + * O(n) at worst + * This function is Linear because it loops over all + * values in the list when trying to remove the back + * value. This function can be constant at best if the + * list is empty. * @return the item that was removed */ @Override @@ -250,7 +292,10 @@ public E removeBack() /** * Remove item from the list - * + * O(n) at best + * O(2n) at worst? + * This function is linear but could potentially + * loop over all values twice. * @param item the item to be removed */ @Override @@ -272,7 +317,11 @@ public void remove(E item) /** * Remove item at a specified index. - * + * O(1) at best + * O(n) at worst + * Very likely to loop over all elements unless + * exceptions are thrown or removeFront() is + * called. * @param index the index where the item should be removed * @return the item that was removed */ @@ -307,7 +356,11 @@ public E remove(int index) /** * Checks if an item is in the list. - * + * O(1) at best + * O(n) at worst + * This function is linear because it will potentially + * loop over all elements in the list, but rarely + * constant if the list is empty. * @param item the item to search for * @return true if the item is in the list, false otherwise */ @@ -331,6 +384,9 @@ public boolean contains(E item) /** * Checks if the list is empty. + * O(1) + * This Function is constant because it is one + * conditional and one return. * * @return true if the list is empty, false otherwise */ @@ -341,6 +397,8 @@ public boolean isEmpty() { /** * Provides a count of the number of items in the list. + * O(1) + * This Function is constant because it is one return. * * @return number of items in the list */ @@ -351,6 +409,9 @@ public int size() { /** * Returns an iterator over elements of type {@code T}. + * O(1) at best + * O(2^n) at worst + * Depends on how it's used in the client code... * * @return an Iterator. */ @@ -371,6 +432,8 @@ public LinkedListIterator() { * 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.) + * O(1) + * This function is constant because it returns a conditional. * * @return {@code true} if the iteration has more elements */ @@ -381,7 +444,8 @@ public boolean hasNext() { /** * Returns the next element in the iteration. - * + * O(1) + * This function is constant because it returns an assignment. * @return the next element in the iteration * @throws NoSuchElementException if the iteration has no more elements */ diff --git a/src/driver/Main.java b/src/driver/Main.java index ec895a8..c8767f8 100644 --- a/src/driver/Main.java +++ b/src/driver/Main.java @@ -25,74 +25,74 @@ public static void main(String[] args) { // to see how IntelliJ IDEA suggests fixing it. System.out.println("Hello and welcome!"); -// class Cat { -// private String breed; -// -// public Cat(String breed) { -// this.breed = breed; -// } -// -// @Override -// public String toString() { -// return breed; -// } -// } -// -// String[] breeds = new String[]{ -// "Tabby", "Siamese", "Calico"}; -// -// ArrayList listOfObjects = new ArrayList<>(); -// listOfObjects.addFront(10); -// listOfObjects.addFront("Fresno"); -// listOfObjects.addFront(ITERATIONS); -// listOfObjects.addFront('a'); -// listOfObjects.addFront(new Cat(breeds[1])); -// listOfObjects.addFront(breeds); -// -// System.out.println(listOfObjects); -// -// listOfObjects.addBack(new Cat(breeds[0])); -// listOfObjects.addBack(new Cat(breeds[1])); -// listOfObjects.addBack(new Cat(breeds[0])); -// listOfObjects.addBack(new Cat(breeds[0])); -// listOfObjects.addBack(new Cat(breeds[0])); -// listOfObjects.addBack(new Cat(breeds[0])); -// System.out.println(listOfObjects); -// -// listOfObjects.set(0, 0); -// System.out.println(listOfObjects); -// -// listOfObjects.set((listOfObjects.size() -1), (listOfObjects.size() - 1)); -// listOfObjects.set(0, "front"); -// System.out.println(listOfObjects.size()); -// System.out.println(listOfObjects); -// -// System.out.println(listOfObjects.removeFront()); -// System.out.println(listOfObjects.removeFront()); -// System.out.println(listOfObjects.removeBack()); -// System.out.println(listOfObjects.removeBack()); -// Cat lion = new Cat("Lion"); -// listOfObjects.addFront(lion); -// -// System.out.println(listOfObjects.contains(lion)); -// listOfObjects.removeBack(); -// listOfObjects.removeBack(); -// listOfObjects.removeBack(); -// listOfObjects.removeBack(); -// listOfObjects.removeBack(); -// System.out.println(listOfObjects.contains("Fresn!")); -// -// System.out.println(listOfObjects); -// -// System.out.println(listOfObjects.contains('a')); -// -// System.out.println(); -// System.out.println(listOfObjects); -// listOfObjects.remove((Object) 'a'); -// System.out.println(listOfObjects); -// -// System.out.println(listOfObjects.remove(0)); -// System.out.println(listOfObjects); + class Cat { + private String breed; + + public Cat(String breed) { + this.breed = breed; + } + + @Override + public String toString() { + return breed; + } + } + + String[] breeds = new String[]{ + "Tabby", "Siamese", "Calico"}; + + ArrayList listOfObjects = new ArrayList<>(); + listOfObjects.addFront(10); + listOfObjects.addFront("Fresno"); + listOfObjects.addFront(ITERATIONS); + listOfObjects.addFront('a'); + listOfObjects.addFront(new Cat(breeds[1])); + listOfObjects.addFront(breeds); + + System.out.println(listOfObjects); + + listOfObjects.addBack(new Cat(breeds[0])); + listOfObjects.addBack(new Cat(breeds[1])); + listOfObjects.addBack(new Cat(breeds[0])); + listOfObjects.addBack(new Cat(breeds[0])); + listOfObjects.addBack(new Cat(breeds[0])); + listOfObjects.addBack(new Cat(breeds[0])); + System.out.println(listOfObjects); + + listOfObjects.set(0, 0); + System.out.println(listOfObjects); + + listOfObjects.set((listOfObjects.size() -1), (listOfObjects.size() - 1)); + listOfObjects.set(0, "front"); + System.out.println(listOfObjects.size()); + System.out.println(listOfObjects); + + System.out.println(listOfObjects.removeFront()); + System.out.println(listOfObjects.removeFront()); + System.out.println(listOfObjects.removeBack()); + System.out.println(listOfObjects.removeBack()); + Cat lion = new Cat("Lion"); + listOfObjects.addFront(lion); + + System.out.println(listOfObjects.contains(lion)); + listOfObjects.removeBack(); + listOfObjects.removeBack(); + listOfObjects.removeBack(); + listOfObjects.removeBack(); + listOfObjects.removeBack(); + System.out.println(listOfObjects.contains("Fresn!")); + + System.out.println(listOfObjects); + + System.out.println(listOfObjects.contains('a')); + + System.out.println(); + System.out.println(listOfObjects); + listOfObjects.remove((Object) 'a'); + System.out.println(listOfObjects); + + System.out.println(listOfObjects.remove(0)); + System.out.println(listOfObjects); @@ -143,23 +143,17 @@ public static void main(String[] args) { linkedList.remove("Toby"); System.out.println(linkedList); -// linkedList.remove((Object) 4); -// System.out.println(linkedList); -// linkedList.remove((Object) 3); -// System.out.println(linkedList); -// linkedList.remove("Howdy"); -// System.out.println(linkedList); -// linkedList.remove((Object) null); -// System.out.println(linkedList); -// linkedList.remove("Howdy"); -// System.out.println(linkedList); - System.out.println(linkedList.remove(0)); System.out.println(linkedList); + System.out.println(); + System.out.println(); + System.out.println(); + System.out.println(); - - - + ArrayList tobysList = new ArrayList<>(); + System.out.println(tobysList); + tobysList.addFront("Toby"); + System.out.println(tobysList.get(0)); } } \ No newline at end of file diff --git a/src/tests/ArrayListTest.java b/src/tests/ArrayListTest.java deleted file mode 100644 index fc431d2..0000000 --- a/src/tests/ArrayListTest.java +++ /dev/null @@ -1,334 +0,0 @@ -package tests; - -import abstractDataTypes.ArrayList; -import interfaces.List; -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -/** - * Test Class for ArrayIntList - * @author tobygoetz - * @version 1.0 - */ -public class ArrayListTest { - public List empty = new ArrayList<>(new String[]{}); - public List nearlyEmpty = new ArrayList<>(new String[]{"Toby"}); - public List notEmpty = new ArrayList<>(new String[]{"Toby", "is", "cool", "!" }); - public List full = new ArrayList<>(new String[] - {"Toby", "is", "cool", "!", " ", "Or", "so", "he", "belives", "!" }); - - public Exception exception; - public static final int ITERATIONS = 15; - - /** - * Test adds Integer values to the front when empty, almost empty, - * not empty and when buffer is larger than intial size of 10 is - * surpassed. - */ - @Test - public void addFrontTest() { - empty.addFront("BOOM"); - - } - } -// -// /** -// * Test adds Integer values to the back when empty, almost empty, -// * not empty and when buffer is larger than intial size of 10 is -// * surpassed. -// */ -// @Test -// public void addBackTest() { -// array.clear(); -// assertEquals(0, array.size()); -// for (int i = 0; i <= ITERATIONS; i++) { -// array.addBack(i); -// // Index 0 changes everytime addFront is called -// assertEquals(i, array.get(array.size() - 1)); -// } -// } -// -// /** -// * Test adds Integer values at specific index when empty, almost -// * empty,not empty and when buffer is larger than intial size of -// * 10 is surpassed. -// */ -// @Test -// public void addTest() { -// array.clear(); -// assertEquals(0, array.size()); -// for (int i = 0; i <= ITERATIONS; i++) { -// array.add(i, i); -// // Index at i incrementing -// assertEquals(i, array.get(i)); -// } -// -// for (int i = ITERATIONS; i >= 0; i--) { -// array.add(i, i); -// // Index at i decrementing -// assertEquals(i, array.get(i)); -// } -// -// //IndexOutOfBoundsException is thrown if -1 is called -// exception = assertThrows( -// IndexOutOfBoundsException.class, () -> { -// array.add(-1, ITERATIONS); -// }); -// -// //IndexOutOfBoundsException is thrown if index larger than -// // the amount of indices is called -// exception = assertThrows( -// IndexOutOfBoundsException.class, () -> { -// array.add(array.size() + 1, ITERATIONS); -// }); -// } -// -// /** -// * Test removes Integer values from the front of ArrayIntList when -// * empty, almost empty and not empty -// */ -// @Test -// public void removeFrontTest() { -// array.clear(); -// assertEquals(0, array.size()); -// -// //test with empty array -// array.removeFront(); -// exception = assertThrows( -// IndexOutOfBoundsException.class, () -> { -// array.get(0); -// }); -// assertTrue(array.isEmpty()); -// -// //test with 1 value in array -// array.addFront(ITERATIONS); -// array.removeFront(); -// assertTrue(array.isEmpty()); -// -// for (int i = 0; i <= ITERATIONS; i++) { -// array.add(i, i); -// } -// for (int i = 0; i < ITERATIONS; i++) { -// int removedValue = array.get(1); -// array.removeFront(); -// assertEquals(removedValue, array.get(0)); -// } -// } -// -// /** -// * Test removes Integer values from the front of ArrayIntList when -// * empty, almost empty and not empty -// */ -// @Test -// public void removeBackTest() { -// array.clear(); -// assertEquals(0, array.size()); -// -// //test with empty array -// array.removeBack(); -// exception = assertThrows( -// IndexOutOfBoundsException.class, () -> { -// array.get(0); -// }); -// assertTrue(array.isEmpty()); -// -// //test with 1 value in array -// array.addFront(ITERATIONS); -// array.removeBack(); -// assertTrue(array.isEmpty()); -// -// //Finish this for removed -//// for (int i = 0; i <= ITERATIONS; i++) { -//// array.add(i, i); -//// } -//// for (int i = 0; i < ITERATIONS; i++) { -//// int removedValue = array.get(1); -//// array.removeFront(); -//// assertEquals(removedValue, array.get(0)); -//// } -// } -// -// /** -// * Test removes Integer values at specific index when empty, almost -// * empty,not empty and when buffer is larger than intial size of -// * 10 is surpassed. -// */ -// @Test -// public void removeTest() { -// array.clear(); -// assertEquals(0, array.size()); -// -// //test with empty array -// exception = assertThrows( -// IndexOutOfBoundsException.class, () -> { -// array.get(0); -// }); -// assertTrue(array.isEmpty()); -// -// //test with index higher than size of array -// exception = assertThrows( -// IndexOutOfBoundsException.class, () -> { -// array.get(array.size()); -// }); -// assertTrue(array.isEmpty()); -// -// //test with one value in array -// array.addFront(0); -// array.remove(0); -// assertTrue(array.isEmpty()); -// assertEquals(0, array.size()); -// -// for (int i = 0; i <= ITERATIONS; i++) { -// array.add(i, i); -// } -// for (int i = 0; i < ITERATIONS; i++) { -// int removedValue = array.get(1); -// array.remove(0); -// assertEquals(removedValue, array.get(0)); -// } -// } -// -// /** -// * Test get method returns for empty, almost empty -// * and exception throw due to Index out of bounds -// */ -// @Test -// public void getTest() { -// array.clear(); -// assertEquals(0, array.size()); -// -// //test with empty array -// exception = assertThrows( -// IndexOutOfBoundsException.class, () -> { -// array.get(0); -// }); -// assertTrue(array.isEmpty()); -// -// //test with index greater than size of array -// //test with empty array -// exception = assertThrows( -// IndexOutOfBoundsException.class, () -> { -// array.get(1); -// }); -// assertTrue(array.isEmpty()); -// -// //reassign values -// this.fillArray(array); -// -// //test the return values of get() -// for (int i = 0; i <= ITERATIONS; i++) { -// int getValue = array.get(i); -// assertEquals(getValue, array.get(i)); -// } -// } -// -// /** -// * Test contains() for non-existent values, existing values, -// * against empty list -// */ -// @Test -// public void containsTest() { -// array.clear(); -// assertEquals(0, array.size()); -// -// //Test if empty -// assertFalse(array.contains(ITERATIONS)); -// -// //Test if value 1 exists -// array.add(0, 1); -// assertTrue(array.contains(1)); -// -// //test if Iterations exists -// this.fillArray(array); -// assertTrue(array.contains(ITERATIONS)); -// -// //test if number does not exist -// assertFalse(array.contains(80085)); -// } -// -// /** -// * Test IndexOf() for no values, some values, -// * against empty list -// */ -// @Test -// public void IndexOfTest() { -// //saftey check -// array.clear(); -// assertEquals(0, array.size()); -// -// //test bounds of IndexOf() -// assertEquals(-1, array.indexOf(-ITERATIONS)); -// -// //test if indices match value returns of all indices -// System.out.println(array); -// for (int i = 0; i < ITERATIONS; i++) { -// array.addBack(i); -// } -// for (int i = 0; i < ITERATIONS; i++) { -// array.addBack(i); -// assertEquals(i, array.indexOf(i)); -// } -// } -// -// /** -// * Test isEmpty() for no values, some values, -// * against empty list -// */ -// @Test -// public void isEmptyTest() { -// //saftey check -// array.clear(); -// assertEquals(0, array.size()); -// -// //test against non-empty array -// this.fillArray(array); -// assertFalse(array.isEmpty()); -// } -// -// /** -// * Test size() for no values, some values, -// * against empty list -// */ -// @Test -// public void sizeTest() { -// //saftey check -// array.clear(); -// assertEquals(0, array.size()); -// -// //test against non-empty array -// for (int i = 0; i < ITERATIONS; i++) { -// array.addBack(i); -// assertEquals(i + 1, array.size()); -// } -// } -// -// /** -// * Test clear() for no values, some values, -// * against empty list -// */ -// @Test -// public void clearTest() { -// //saftey check -// array.clear(); -// assertEquals(0, array.size()); -// -// //test against non-empty array -// this.fillArray(array); -// array.clear(); -// assertEquals(0, array.size()); -// } -// -// /** -// * Helper method to fill the array in this class -// * @param arr Field array -// */ -// public void fillArray(ArrayIntList arr) { -// //reassign values -// for (int i = 0; i <= ITERATIONS; i++) { -// array.addFront(i); -// // Index 0 changes everytime addFront is called -// assertEquals(i, array.get(0)); -// } -// } - diff --git a/tests/ArrayListTest.java b/tests/ArrayListTest.java index 1d91d5e..f3716cb 100644 --- a/tests/ArrayListTest.java +++ b/tests/ArrayListTest.java @@ -1,330 +1,320 @@ import abstractDataTypes.ArrayList; -import interfaces.List; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.*; + /** * Test Class for ArrayIntList * @author tobygoetz * @version 1.0 */ -public class ArrayListTest { - public List empty = new ArrayList<>(new String[]{}); - public List nearlyEmpty = new ArrayList<>(new String[]{"Toby"}); - public List notEmpty = new ArrayList<>(new String[]{"Toby", "is", "cool", "!" }); - public List full = new ArrayList<>(new String[] - {"Toby", "is", "cool", "!", " ", "Or", "so", "he", "belives", "!" }); +public class ArrayListTest { + private ArrayList testArrayList = new ArrayList<>((E[]) new Object[]{}); + private E[] genericArray = (E[]) new Object[]{ + "Test", 1, 'a', Math.random(), 1L, (byte) 0x00, 7, 8, 9, 10, "Eleven", "Twelve"}; + private Exception exception; + private static final int ITERATIONS = 15; - public Exception exception; - public static final int ITERATIONS = 15; + /** + * Test adds genericArray values to the front when empty, almost empty, + * not empty and when buffer is larger than the initial size of 10 is + * surpassed. + */ + @Test + public void addFrontTest() + { + for (int i = 0; i < genericArray.length; i++) { + testArrayList.addFront(genericArray[i]); + assertEquals(genericArray[i], testArrayList.get(0)); + } + } /** - * Test adds Integer values to the front when empty, almost empty, - * not empty and when buffer is larger than intial size of 10 is + * Test adds genericArray values to the back when empty, almost empty, + * not empty and when buffer is larger than initial size of 10 is * surpassed. */ @Test - public void addFrontTest() { - empty.addFront("BOOM"); + public void addBackTest() + { + for (int i = 0; i < genericArray.length; i++) { + testArrayList.addBack(genericArray[i]); + // Index 0 changes everytime addFront is called + assertEquals(genericArray[i], testArrayList.get(testArrayList.size() - 1)); + } + } + + /** + * Test adds Integer values at specific index when empty, almost + * empty,not empty and when buffer is larger than initial size of + * 10 is surpassed. + */ + @Test + public void addTest() + { + // Adds Index at i incrementing + for (int i = 0; i < ITERATIONS; i++) { + testArrayList.add(i, (E) (Integer) i); + assertEquals(i, testArrayList.get(i)); + } + + // Adds Index at i decrementing + for (int i = ITERATIONS; i >= 0; i--) { + testArrayList.add(i, (E) (Integer) i); + assertEquals(i, testArrayList.get(i)); + } + + //IndexOutOfBoundsException is thrown if -1 is called + exception = assertThrows( + IndexOutOfBoundsException.class, () -> { + testArrayList.add(-1, (E) (Integer) ITERATIONS); + }); + + //IndexOutOfBoundsException is thrown if index larger than size of ArrayList is requested + exception = assertThrows( + IndexOutOfBoundsException.class, () -> { + testArrayList.add(testArrayList.size() + 1, (E) (Integer) ITERATIONS); + }); + } + + /** + * Tests if values at specific index have been set when empty, + * almost empty,not empty and when buffer is larger than initial + * size of 10 is surpassed. Tests exceptions when attempting to + * set index that is out of range. + * */ + @Test + public void setTest() { + + assertTrue(testArrayList.isEmpty()); + + //IndexOutOfBoundsException is thrown if -1 is called + exception = assertThrows( + IndexOutOfBoundsException.class, () -> { + testArrayList.set(-1, (E) (Integer) ITERATIONS); + }); + + //IndexOutOfBoundsException is thrown if index larger than size of ArrayList is requested + exception = assertThrows( + IndexOutOfBoundsException.class, () -> { + testArrayList.set(testArrayList.size() + 1, (E) (Integer) ITERATIONS); + }); + + //reassign values + this.fillArray(); + assertFalse(testArrayList.isEmpty()); + for (int i = 0; i < genericArray.length; i++) { + testArrayList.set(i, (E)(Integer) ITERATIONS); + assertEquals(ITERATIONS, testArrayList.get(i)); + } + } + + /** + * Test removes Integer values from the front of ArrayIntList when + * empty, almost empty and not empty. Asserts that null is returned + * when removeFront() is called don an empty array. + */ + @Test + public void removeFrontTest() + { + //test that an empty array returns null when removeFront() is called + testArrayList.removeFront(); + assertTrue(testArrayList.isEmpty()); + assertNull(testArrayList.removeFront()); + + + //test with 1 value in array + testArrayList.addFront((E) (Integer) ITERATIONS); + testArrayList.removeFront(); + assertTrue(testArrayList.isEmpty()); + + //fill the Array + for (int i = 0; i <= ITERATIONS; i++) { + testArrayList.add(i, (E) (Integer) i); + } + for (int i = 0; i < ITERATIONS; i++) { + E removedValue = testArrayList.get(1); + testArrayList.removeFront(); + assertEquals(removedValue, testArrayList.get(0)); + } + } + + /** + * Test removes Integer values from the front of ArrayIntList when + * empty, almost empty and not empty. Asserts that null is returned + * when removeBack() is called don an empty array. + */ + @Test + public void removeBackTest() + { + //test with empty array + assertTrue(testArrayList.isEmpty()); + assertNull(testArrayList.removeBack()); + + //reassign values + this.fillArray(); + for (int i = 0; i < genericArray.length; i++) { + E removedValue = testArrayList.get(testArrayList.size() - 1); + assertEquals(removedValue, testArrayList.removeBack()); + } + } + + /** + * Test removes genericArray values at specific index when empty, almost + * empty,not empty and when buffer is larger than initial size of + * 10 is surpassed. + */ + @Test + public void removeIndexTest() + { + //test with empty array + assertTrue(testArrayList.isEmpty()); + exception = assertThrows( + IndexOutOfBoundsException.class, () -> { + testArrayList.remove(0); + }); + //test with index greater than size of array + exception = assertThrows( + IndexOutOfBoundsException.class, () -> { + testArrayList.remove(1); + }); + + //reassign values + this.fillArray(); + assertFalse(testArrayList.isEmpty()); + + //test with index greater than size of array + exception = assertThrows( + IndexOutOfBoundsException.class, () -> { + testArrayList.remove(testArrayList.size()); + }); + + for (int i = 0; i < genericArray.length - 1; i++) { + E valueAfterRemoved = testArrayList.get(1); + testArrayList.remove(0); + assertEquals(valueAfterRemoved, testArrayList.get(0)); + } + } + + /** + * Test removes genericArray values if present when empty, almost + * empty,not empty and when buffer is larger than initial size of + * 10 is surpassed. + */ + @Test + public void removeItemTest() { + + assertTrue(testArrayList.isEmpty()); + + //reassign values at back to maintain order of genericArray + for (int i = 0; i < genericArray.length; i++) { + testArrayList.addBack(genericArray[i]); + } + assertFalse(testArrayList.isEmpty()); + + for (int i = 0; i < genericArray.length; i++) { + E valueRemoved = testArrayList.get(i); + testArrayList.remove(genericArray[i]); + testArrayList.addFront((E)(Integer) ITERATIONS); + assertFalse(testArrayList.contains(valueRemoved)); + } + } + + /** + * Test get method returns for empty, almost empty + * and exception throw due to Index out of bounds + */ + @Test + public void getTest() + { + //test with empty array + assertTrue(testArrayList.isEmpty()); + + exception = assertThrows( + IndexOutOfBoundsException.class, () -> { + testArrayList.get(0); + }); + + //test with index greater than size of array + exception = assertThrows( + IndexOutOfBoundsException.class, () -> { + testArrayList.get(1); + }); + + //reassign values at back to maintain order of genericArray + for (int i = 0; i < genericArray.length; i++) { + testArrayList.addBack(genericArray[i]); + } + assertFalse(testArrayList.isEmpty()); + + //test the return values of get() + for (int i = 0; i < genericArray.length; i++) { + assertEquals(genericArray[i], testArrayList.get(i)); + } + } + + /** + * Test contains() for non-existent values, existing values, + * against empty list + */ + @Test + public void containsTest() + { + //Test if empty + assertTrue(testArrayList.isEmpty()); + assertFalse(testArrayList.contains(ITERATIONS)); + + //Test if value 1 exists + testArrayList.add(0, (E)(Integer) ITERATIONS); + assertTrue(testArrayList.contains(ITERATIONS)); + + //test if number does not exist + assertFalse(testArrayList.contains(80085)); + } + + /** + * Test isEmpty() against empty and non-empty ArrayList + */ + @Test + public void isEmptyTest() + { + //test against empty array + assertTrue(testArrayList.isEmpty()); + + //test against non-empty array + this.fillArray(); + assertFalse(testArrayList.isEmpty()); + } + + /** + * Test size() for no values, some values, + * against empty list + */ + @Test + public void sizeTest() + { + //test against empty ArrayList + assertTrue(testArrayList.isEmpty()); + assertEquals(0, testArrayList.size()); + + //test against non-empty ArrayList + for (int i = 0; i < ITERATIONS; i++) { + testArrayList.addBack((E)(Integer) i); + assertEquals(i + 1, testArrayList.size()); + } + } + + /* + * Helper method to fill the array in this class + */ + private void fillArray() + { + //reassign values + for (int i = 0; i < genericArray.length; i++) { + testArrayList.addFront(genericArray[i]); + assertEquals(genericArray[i], testArrayList.get(0)); } } -// -// /** -// * Test adds Integer values to the back when empty, almost empty, -// * not empty and when buffer is larger than intial size of 10 is -// * surpassed. -// */ -// @Test -// public void addBackTest() { -// array.clear(); -// assertEquals(0, array.size()); -// for (int i = 0; i <= ITERATIONS; i++) { -// array.addBack(i); -// // Index 0 changes everytime addFront is called -// assertEquals(i, array.get(array.size() - 1)); -// } -// } -// -// /** -// * Test adds Integer values at specific index when empty, almost -// * empty,not empty and when buffer is larger than intial size of -// * 10 is surpassed. -// */ -// @Test -// public void addTest() { -// array.clear(); -// assertEquals(0, array.size()); -// for (int i = 0; i <= ITERATIONS; i++) { -// array.add(i, i); -// // Index at i incrementing -// assertEquals(i, array.get(i)); -// } -// -// for (int i = ITERATIONS; i >= 0; i--) { -// array.add(i, i); -// // Index at i decrementing -// assertEquals(i, array.get(i)); -// } -// -// //IndexOutOfBoundsException is thrown if -1 is called -// exception = assertThrows( -// IndexOutOfBoundsException.class, () -> { -// array.add(-1, ITERATIONS); -// }); -// -// //IndexOutOfBoundsException is thrown if index larger than -// // the amount of indices is called -// exception = assertThrows( -// IndexOutOfBoundsException.class, () -> { -// array.add(array.size() + 1, ITERATIONS); -// }); -// } -// -// /** -// * Test removes Integer values from the front of ArrayIntList when -// * empty, almost empty and not empty -// */ -// @Test -// public void removeFrontTest() { -// array.clear(); -// assertEquals(0, array.size()); -// -// //test with empty array -// array.removeFront(); -// exception = assertThrows( -// IndexOutOfBoundsException.class, () -> { -// array.get(0); -// }); -// assertTrue(array.isEmpty()); -// -// //test with 1 value in array -// array.addFront(ITERATIONS); -// array.removeFront(); -// assertTrue(array.isEmpty()); -// -// for (int i = 0; i <= ITERATIONS; i++) { -// array.add(i, i); -// } -// for (int i = 0; i < ITERATIONS; i++) { -// int removedValue = array.get(1); -// array.removeFront(); -// assertEquals(removedValue, array.get(0)); -// } -// } -// -// /** -// * Test removes Integer values from the front of ArrayIntList when -// * empty, almost empty and not empty -// */ -// @Test -// public void removeBackTest() { -// array.clear(); -// assertEquals(0, array.size()); -// -// //test with empty array -// array.removeBack(); -// exception = assertThrows( -// IndexOutOfBoundsException.class, () -> { -// array.get(0); -// }); -// assertTrue(array.isEmpty()); -// -// //test with 1 value in array -// array.addFront(ITERATIONS); -// array.removeBack(); -// assertTrue(array.isEmpty()); -// -// //Finish this for removed -//// for (int i = 0; i <= ITERATIONS; i++) { -//// array.add(i, i); -//// } -//// for (int i = 0; i < ITERATIONS; i++) { -//// int removedValue = array.get(1); -//// array.removeFront(); -//// assertEquals(removedValue, array.get(0)); -//// } -// } -// -// /** -// * Test removes Integer values at specific index when empty, almost -// * empty,not empty and when buffer is larger than intial size of -// * 10 is surpassed. -// */ -// @Test -// public void removeTest() { -// array.clear(); -// assertEquals(0, array.size()); -// -// //test with empty array -// exception = assertThrows( -// IndexOutOfBoundsException.class, () -> { -// array.get(0); -// }); -// assertTrue(array.isEmpty()); -// -// //test with index higher than size of array -// exception = assertThrows( -// IndexOutOfBoundsException.class, () -> { -// array.get(array.size()); -// }); -// assertTrue(array.isEmpty()); -// -// //test with one value in array -// array.addFront(0); -// array.remove(0); -// assertTrue(array.isEmpty()); -// assertEquals(0, array.size()); -// -// for (int i = 0; i <= ITERATIONS; i++) { -// array.add(i, i); -// } -// for (int i = 0; i < ITERATIONS; i++) { -// int removedValue = array.get(1); -// array.remove(0); -// assertEquals(removedValue, array.get(0)); -// } -// } -// -// /** -// * Test get method returns for empty, almost empty -// * and exception throw due to Index out of bounds -// */ -// @Test -// public void getTest() { -// array.clear(); -// assertEquals(0, array.size()); -// -// //test with empty array -// exception = assertThrows( -// IndexOutOfBoundsException.class, () -> { -// array.get(0); -// }); -// assertTrue(array.isEmpty()); -// -// //test with index greater than size of array -// //test with empty array -// exception = assertThrows( -// IndexOutOfBoundsException.class, () -> { -// array.get(1); -// }); -// assertTrue(array.isEmpty()); -// -// //reassign values -// this.fillArray(array); -// -// //test the return values of get() -// for (int i = 0; i <= ITERATIONS; i++) { -// int getValue = array.get(i); -// assertEquals(getValue, array.get(i)); -// } -// } -// -// /** -// * Test contains() for non-existent values, existing values, -// * against empty list -// */ -// @Test -// public void containsTest() { -// array.clear(); -// assertEquals(0, array.size()); -// -// //Test if empty -// assertFalse(array.contains(ITERATIONS)); -// -// //Test if value 1 exists -// array.add(0, 1); -// assertTrue(array.contains(1)); -// -// //test if Iterations exists -// this.fillArray(array); -// assertTrue(array.contains(ITERATIONS)); -// -// //test if number does not exist -// assertFalse(array.contains(80085)); -// } -// -// /** -// * Test IndexOf() for no values, some values, -// * against empty list -// */ -// @Test -// public void IndexOfTest() { -// //saftey check -// array.clear(); -// assertEquals(0, array.size()); -// -// //test bounds of IndexOf() -// assertEquals(-1, array.indexOf(-ITERATIONS)); -// -// //test if indices match value returns of all indices -// System.out.println(array); -// for (int i = 0; i < ITERATIONS; i++) { -// array.addBack(i); -// } -// for (int i = 0; i < ITERATIONS; i++) { -// array.addBack(i); -// assertEquals(i, array.indexOf(i)); -// } -// } -// -// /** -// * Test isEmpty() for no values, some values, -// * against empty list -// */ -// @Test -// public void isEmptyTest() { -// //saftey check -// array.clear(); -// assertEquals(0, array.size()); -// -// //test against non-empty array -// this.fillArray(array); -// assertFalse(array.isEmpty()); -// } -// -// /** -// * Test size() for no values, some values, -// * against empty list -// */ -// @Test -// public void sizeTest() { -// //saftey check -// array.clear(); -// assertEquals(0, array.size()); -// -// //test against non-empty array -// for (int i = 0; i < ITERATIONS; i++) { -// array.addBack(i); -// assertEquals(i + 1, array.size()); -// } -// } -// -// /** -// * Test clear() for no values, some values, -// * against empty list -// */ -// @Test -// public void clearTest() { -// //saftey check -// array.clear(); -// assertEquals(0, array.size()); -// -// //test against non-empty array -// this.fillArray(array); -// array.clear(); -// assertEquals(0, array.size()); -// } -// -// /** -// * Helper method to fill the array in this class -// * @param arr Field array -// */ -// public void fillArray(ArrayIntList arr) { -// //reassign values -// for (int i = 0; i <= ITERATIONS; i++) { -// array.addFront(i); -// // Index 0 changes everytime addFront is called -// assertEquals(i, array.get(0)); -// } -// } +} diff --git a/tests/LinkedIntListTest.java b/tests/LinkedIntListTest.java new file mode 100644 index 0000000..c390399 --- /dev/null +++ b/tests/LinkedIntListTest.java @@ -0,0 +1,343 @@ +import abstractDataTypes.LinkedList; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertFalse; + +/** + * Test Class for ArrayIntList + * @author tobygoetz + * @version 1.0 + */ +public class LinkedIntListTest { + private LinkedList testLinkedList = new LinkedList<>(); + private E[] genericArray = (E[]) new Object[]{ + "Test", 1, 'a', Math.random(), 1L, (byte) 0x00, 7, 8, 9, 10, "Eleven", "Twelve"}; + private static final int ITERATIONS = 15; + private Exception exception; + + protected void setException(Exception exception) { + this.exception = exception; + } + + /** + * Test adds Integer values to the front when empty, almost empty, + * not empty and when buffer is larger than intial size of 10 is + * surpassed. + */ + @Test + public void addFrontTest() { + assertEquals(0, testLinkedList.size()); + for (int i = 0; i < genericArray.length; i++) { + testLinkedList.addFront(genericArray[i]); + // Index 0 changes everytime addFront is called + assertEquals(genericArray[i], testLinkedList.get(0)); + } + } + + /** + * Test adds Integer values to the back when empty, almost empty, + * not empty and when buffer is larger than intial size of 10 is + * surpassed. + */ + @Test + public void addBackTest() { + assertEquals(0, testLinkedList.size()); + for (int i = 0; i < genericArray.length; i++) { + testLinkedList.addBack(genericArray[i]); + // Index 0 changes everytime addFront is called + assertEquals(genericArray[i], testLinkedList.get(testLinkedList.size() - 1)); + } + } + + /** + * Test adds Integer values at specific index when empty, almost + * empty,not empty and when buffer is larger than intial size of + * 10 is surpassed. + */ + @Test + public void addTest() + { + // Adds Index at i incrementing + for (int i = 0; i < ITERATIONS; i++) { + testLinkedList.add(i, (E) (Integer) i); + assertEquals(i, testLinkedList.get(i)); + } + + // Adds Index at i decrementing + for (int i = ITERATIONS; i >= 0; i--) { + testLinkedList.add(i, (E) (Integer) i); + assertEquals(i, testLinkedList.get(i)); + } + + + //IndexOutOfBoundsException is thrown if -1 is called + setException(assertThrows( + IndexOutOfBoundsException.class, + () -> testLinkedList.add(-1, (E)(Integer) ITERATIONS))); + + //IndexOutOfBoundsException is thrown if index larger than + // the amount of indices is called + setException(assertThrows( + IndexOutOfBoundsException.class, + () -> testLinkedList.add(testLinkedList.size() + 1, (E)(Integer)ITERATIONS))); + } + + /** + * Tests if values at specific index have been set when empty, + * almost empty,not empty and when buffer is larger than intial + * size of 10 is surpassed. Tests exceptions when attempting to + * set index that is out of range. + * */ + @Test + public void setTest() { + + assertTrue(testLinkedList.isEmpty()); + + //IndexOutOfBoundsException is thrown if -1 is called + exception = assertThrows( + IndexOutOfBoundsException.class, () -> { + testLinkedList.set(-1, (E) (Integer) ITERATIONS); + }); + + //IndexOutOfBoundsException is thrown if index larger than size of ArrayList is requested + exception = assertThrows( + IndexOutOfBoundsException.class, () -> { + testLinkedList.set(testLinkedList.size() + 1, (E) (Integer) ITERATIONS); + }); + + //reassign values + this.fillArray(); + assertFalse(testLinkedList.isEmpty()); + for (int i = 0; i < genericArray.length; i++) { + testLinkedList.set(i, (E)(Integer) ITERATIONS); + assertEquals(ITERATIONS, testLinkedList.get(i)); + } + } + + /** + * Test removes Integer values from the front of ArrayIntList when + * empty, almost empty and not empty + */ + @Test + public void removeFrontTest() { + assertEquals(0, testLinkedList.size()); + + //test with empty array + testLinkedList.removeFront(); + setException(assertThrows( + IndexOutOfBoundsException.class, () -> testLinkedList.get(0))); + assertTrue(testLinkedList.isEmpty()); + + //test with 1 value in array + testLinkedList.addFront((E)(Integer) ITERATIONS); + testLinkedList.removeFront(); + assertTrue(testLinkedList.isEmpty()); + + /* Check that next index value is now equal to index 0 + after the first index is removed */ + + this.fillArray(); + for (int i = 0; i < genericArray.length; i++) { + if (testLinkedList.size() > 1) { + E nextIndex = testLinkedList.get(1); + testLinkedList.removeFront(); + assertEquals(nextIndex, testLinkedList.get(0)); + } else { + testLinkedList.removeFront(); + assertTrue(testLinkedList.isEmpty()); + } + } + } + + /** + * Test removes Integer values from the front of ArrayIntList when + * empty, almost empty and not empty + */ + @Test + public void removeBackTest() + { + assertEquals(0, testLinkedList.size()); + assertNull(testLinkedList.removeBack()); + + //test with empty array + testLinkedList.removeBack(); + setException(assertThrows( + IndexOutOfBoundsException.class, () -> testLinkedList.get(0))); + assertTrue(testLinkedList.isEmpty()); + + //test with 1 value in array + testLinkedList.addFront((E)(Integer) ITERATIONS); + testLinkedList.removeBack(); + assertTrue(testLinkedList.isEmpty()); + + /* Check that next index value is now equal to index 0 + after the first index is removed */ + this.fillArray(); + this.fillArray(); + for (int i = 0; i < genericArray.length; i++) { + E removedValue = testLinkedList.get(testLinkedList.size() - 1); + assertEquals(removedValue, testLinkedList.removeBack()); + } + } + + /** + * Test removes genericArray values at specific index when empty, almost + * empty,not empty and when buffer is larger than intial size of + * 10 is surpassed. + */ + @Test + public void removeIndexTest() + { + //test with empty array + assertTrue(testLinkedList.isEmpty()); + exception = assertThrows( + IndexOutOfBoundsException.class, () -> { + testLinkedList.remove(0); + }); + + //test with index greater than size of array + exception = assertThrows( + IndexOutOfBoundsException.class, () -> { + testLinkedList.remove(1); + }); + + //reassign values + this.fillArray(); + assertFalse(testLinkedList.isEmpty()); + + //test with index greater than size of array + exception = assertThrows( + IndexOutOfBoundsException.class, () -> { + testLinkedList.remove(testLinkedList.size()); + }); + + for (int i = 0; i < genericArray.length - 1; i++) { + E valueAfterRemoved = testLinkedList.get(1); + testLinkedList.remove(0); + assertEquals(valueAfterRemoved, testLinkedList.get(0)); + } + } + + /** + * Test removes genericArray values if present when empty, almost + * empty,not empty and when buffer is larger than intial size of + * 10 is surpassed. + */ + @Test + public void removeItemTest() { + + assertTrue(testLinkedList.isEmpty()); + + //reassign values at back to maintain order of genericArray + for (int i = 0; i < genericArray.length; i++) { + testLinkedList.addBack(genericArray[i]); + } + assertFalse(testLinkedList.isEmpty()); + + for (int i = 0; i < genericArray.length; i++) { + E valueRemoved = testLinkedList.get(i); + testLinkedList.remove(genericArray[i]); + testLinkedList.addFront((E)(Integer) ITERATIONS); + assertFalse(testLinkedList.contains(valueRemoved)); + } + } + + /** + * Test get method returns for empty, almost empty + * and exception throw due to Index out of bounds + */ + @Test + public void getTest() { + assertEquals(0, testLinkedList.size()); + + //test with empty array + setException(assertThrows( + IndexOutOfBoundsException.class, () -> testLinkedList.get(0))); + assertTrue(testLinkedList.isEmpty()); + + //test with index greater than size of array + //test with empty array + setException(assertThrows( + IndexOutOfBoundsException.class, () -> testLinkedList.get(1))); + assertTrue(testLinkedList.isEmpty()); + + //reassign values at back to maintain order of genericArray + for (int i = 0; i < genericArray.length; i++) { + testLinkedList.addBack(genericArray[i]); + } + assertFalse(testLinkedList.isEmpty()); + + //test the return values of get() + for (int i = 0; i < genericArray.length; i++) { + assertEquals(genericArray[i], testLinkedList.get(i)); + } + } + + /** + * Test contains() for non-existent values, existing values, + * against empty list + */ + @Test + public void containsTest() + { + //Test if empty + assertEquals(0, testLinkedList.size()); + assertFalse(testLinkedList.contains((E)(Integer) ITERATIONS)); + + //Test if value 1 exists + testLinkedList.add(0, (E)(Integer) 1); + assertTrue(testLinkedList.contains((E)(Integer) 1)); + + //test if Iterations exists + this.fillArray(); + testLinkedList.set(0, (E)(Integer) ITERATIONS); + assertTrue(testLinkedList.contains((E)(Integer) ITERATIONS)); + + //test if number does not exist + assertFalse(testLinkedList.contains((E)(Integer) 80085)); + } + + /** + * Test isEmpty() for no values, some values, + * against empty list + */ + @Test + public void isEmptyTest() + { + //test against empty array + assertEquals(0, testLinkedList.size()); + + //test against non-empty array + this.fillArray(); + assertFalse(testLinkedList.isEmpty()); + } + + /** + * Test size() for no values, some values, + * against empty list + */ + @Test + public void sizeTest() { + //saftey check + assertEquals(0, testLinkedList.size()); + + //test against non-empty array + for (int i = 0; i < ITERATIONS; i++) { + testLinkedList.addBack((E)(Integer) i); + assertEquals(i + 1, testLinkedList.size()); + } + } + + /* + * Helper method to fill the array in this class + */ + private void fillArray() + { + //reassign values + for (int i = 0; i < genericArray.length; i++) { + testLinkedList.addFront(genericArray[i]); + assertEquals(genericArray[i], testLinkedList.get(0)); + } + } +} From daf81db709b06133064e98deacf6e6ed90ed7553 Mon Sep 17 00:00:00 2001 From: tobygoetz Date: Thu, 15 Feb 2024 17:28:47 -0800 Subject: [PATCH 10/10] Ready for review: Term Project 2. Created Bag API, LinkedBag, LinkedQueue, LinkedStack, QueueTestClient, ResizingArrayStack, StackTestClient and Stats. Implemented methods for each of these classes and tested with Client program code. Documented all methods with runtime analysis. --- src/abstractDataTypes/LinkedBag.java | 169 +++++++++++++++ src/abstractDataTypes/LinkedQueue.java | 201 ++++++++++++++++++ src/abstractDataTypes/LinkedStack.java | 199 +++++++++++++++++ src/abstractDataTypes/ResizingArrayStack.java | 174 +++++++++++++++ src/driver/QueueTestClient.java | 39 ++++ src/driver/StackTestClient.java | 64 ++++++ src/driver/Stats.java | 37 ++++ src/interfaces/Bag.java | 27 +++ 8 files changed, 910 insertions(+) create mode 100644 src/abstractDataTypes/LinkedBag.java create mode 100644 src/abstractDataTypes/LinkedQueue.java create mode 100644 src/abstractDataTypes/LinkedStack.java create mode 100644 src/abstractDataTypes/ResizingArrayStack.java create mode 100644 src/driver/QueueTestClient.java create mode 100644 src/driver/StackTestClient.java create mode 100644 src/driver/Stats.java create mode 100644 src/interfaces/Bag.java diff --git a/src/abstractDataTypes/LinkedBag.java b/src/abstractDataTypes/LinkedBag.java new file mode 100644 index 0000000..45d3438 --- /dev/null +++ b/src/abstractDataTypes/LinkedBag.java @@ -0,0 +1,169 @@ +/** + * Toby Goetz + */ + +package abstractDataTypes; + +import interfaces.Bag; +import java.util.Iterator; +import java.util.ListIterator; + +/** + * @author Book People + * @version 1.0 + * @param + */ +public class LinkedBag implements Bag +{ + private Node first; + private int size; + private class Node + { + E item; + Node next; + + private Node(E item) + { + this.item = item; + } + + @Override + public String toString() { + return "Node{" + + "item=" + item + + ", next=" + next + + '}'; + } + } + + /** + * Add an item to the Bag. + * O(1) at worst + * This function is constant at worst because it only makes + * a few assignments at the front of the list + * @param item data value of any type + */ + @Override + public void add(E item) + { // Add item to the bag + Node oldFirst = first; + first = new Node(item); + first.next = oldFirst; + size++; + } + + /** + * Checks to see if the bag is empty. + * O(1) at worst + * This function is constant because it acceses an + * instance variable and returns a boolean value + * @return boolean true if bag is empty, false otherwise + */ + @Override + public boolean isEmpty() { + return first == null; + } + + /** + * Returns a count of the number of items in the Bag. + * O(1) at worst + * This function is constant at worst because it + * only accesses an instance variable + * @return the number of items in the stack + */ + @Override + public int size() { + return size; + } + + /** + * Returns an iterator over elements of type {@code T}. + * O(n) at worst + * This function is linear at worst because it loops over + * all elements in the array. It could be Constant if the array + * is empty. Depends on how the client code uses it. + * @return an Iterator. + */ + @Override + public Iterator iterator() + { + return new ListIterator<>() + { + private Node current = first; + + @Override + public boolean hasNext() + { + return current != null; + } + + @Override + public E next() + { + E item = current.item; + current = current.next; + return item; + } + + @Override + public boolean hasPrevious() { + return false; + } + + @Override + public E previous() { + return null; + } + + @Override + public int nextIndex() { + return 0; + } + + @Override + public int previousIndex() { + return 0; + } + + @Override + public void remove() { + + } + + @Override + public void set(E item) { + + } + + @Override + public void add(E item) { + + } + }; + } + + /** + * O(n) at worst + * This function is linear at worst because it loops over + * all elements in the array. It could be Constant if the array + * is empty. + * @return String value representing the Bag + */ + @Override + public String toString() { + Node current = first; + String nodes = ""; + if (current != null) { + nodes += (current.item + ", "); + while (current.next != null) { + current = current.next; + nodes += (current.item); + if (current.next != null) { + nodes += ", "; + } + } + } + return "LinkedBag{" + "size=" + size + + "[" + nodes + "]}"; + } +} diff --git a/src/abstractDataTypes/LinkedQueue.java b/src/abstractDataTypes/LinkedQueue.java new file mode 100644 index 0000000..5778974 --- /dev/null +++ b/src/abstractDataTypes/LinkedQueue.java @@ -0,0 +1,201 @@ +/** + * Toby Goetz + */ + +package abstractDataTypes; + +import interfaces.Queue; +import java.util.Iterator; +import java.util.ListIterator; + +/** + * @author Book People + * @version 1.0 + * @param + */ +public class LinkedQueue implements Queue +{ + private Node first; + private Node last; + private int size; + + private class Node + { + E item; + Node next; + + private Node(E item) + { + this.item = item; + } + + @Override + public String toString() { + return "Node{" + + "item=" + item + + ", next=" + next + + '}'; + } + } + + /** + * Add an item to the queue. + * O(1) at worst + * This function is constant at worst because it only makes + * a few assignments at the front of the list and isEmpty() + * is constant as well + * @param item the item to be added + */ + @Override + public void enqueue(E item) + { // Add item to the end of the list. + Node oldLast = last; + last = new Node(item); + last.next = null; + + if (isEmpty()) { + first = last; + } else { + oldLast.next = last; + } size++; + } + + /** + * Remove an item from the queue. + * O(1) at worst + * This function is constant at worst because it only makes + * a few assignments at the front of the list and isEmpty() + * is constant as well + * @return the item that was removed + */ + @Override + public E dequeue() + { // Remove item from the beginning of the list. + E item = first.item; + first = first.next; + + if ( isEmpty()) { + last = null; + } size--; + + return item; + } + + /** + * Checks to see if the queue is empty. + * O(1) at worst + * This function is constant because it acceses an + * instance variable and returns a boolean value + * @return true if the queue is empty, false otherwise + */ + @Override + public boolean isEmpty() + { + return first == null; + } + + /** + * Returns a count of the number of items in the queue. + * O(1) at worst + * This function is constant at worst because it + * only accesses an instance variable + * @return the number of items in the queue + */ + @Override + public int size() + { + return size; + } + + /** + * Returns an iterator over elements of type {@code T}. + * O(n) at worst + * This function is linear at worst because it loops over + * all elements in the array. It could be Constant if the array + * is empty. Depends on how the client code uses it. + * @return an Iterator. + */ + @Override + public Iterator iterator() + { + return new ListIterator<>() + { + private Node current = first; + + @Override + public boolean hasNext() { + return current != null; + } + + @Override + public E next() { + E item = current.item; + current = current.next; + return item; + } + + @Override + public boolean hasPrevious() { + return false; + } + + @Override + public E previous() { + return null; + } + + @Override + public int nextIndex() { + return 0; + } + + @Override + public int previousIndex() { + return 0; + } + + @Override + public void remove() { + + } + + @Override + public void set(E item) { + + } + + @Override + public void add(E item) { + + } + }; + } + + /** + * O(n) at worst + * This function is linear at worst because it loops over + * all elements in the array. It could be Constant if the array + * is empty. + * @return String value representing the queue + */ + @Override + public String toString() + { + Node current = first; + String nodes = ""; + if (current != null) { + nodes += (current.item + ", "); + while (current.next != null) { + current = current.next; + nodes += (current.item); + if (current.next != null) { + nodes += ", "; + } + } + } + return "LinkedQueue{" + + "(" + size + " left on stack) " + + nodes; + + } +} diff --git a/src/abstractDataTypes/LinkedStack.java b/src/abstractDataTypes/LinkedStack.java new file mode 100644 index 0000000..9be839e --- /dev/null +++ b/src/abstractDataTypes/LinkedStack.java @@ -0,0 +1,199 @@ +/** + * Toby Goetz + */ + +package abstractDataTypes; + +import interfaces.Stack; +import java.util.Iterator; +import java.util.ListIterator; + +/** + * @author Book People + * @version 1.0 + * @param + */ +public class LinkedStack implements Stack { + + private Node first; + private int size; + + private class Node + { // Nested class to define Node + E item; + Node next; + + private Node(E item) + { + this.item = item; + } + + @Override + public String toString() { + return "Node{" + + "item=" + item + + ", next=" + next + + '}'; + } + } + + /** + * Add an item to the stack. + * O(1) at worst + * This function is constant at worst because it only makes + * a few assignments at the front of the list + * @param item the item to be added + */ + @Override + public void push(E item) + { // Add item to the top of the stack + Node oldFirst = first; + first = new Node(item); + first.next = oldFirst; + size++; + } + + /** + * Removes the most recently added item from the stack. + * O(1) at worst + * This function is constant at worst because it only makes + * a few assignments at the front of the list + * @return the item that was removed + */ + @Override + public E pop() + { // Remove item from the top of the stack + E item = first.item; + first = first.next; + size--; + return item; + } + + /** + * Returns the item at the top of the stack. + * Does not modify the stack or the item at the top. + * O(1) at worst + * This function is constant because it accesses an + * element in an array + * @return item at the top of the stack. + */ + @Override + public E peek() { + return first.item; + } + + /** + * Checks to see if the stack is empty. + * O(1) at worst + * This function is constant because it acceses an + * instance variable and returns a boolean value + * @return true if the stack is empty, false otherwise + */ + @Override + public boolean isEmpty() { + return first == null; + } + + /** + * Returns a count of the number of items in the stack. + * O(1) at worst + * This function is constant at worst because it + * only accesses an instance variable + * @return the number of items in the stack + */ + @Override + public int size() { + return size; + } + + /** + * Returns an iterator over elements of type {@code T}. + * O(n) at worst + * This function is linear at worst because it loops over + * all elements in the array. It could be Constant if the array + * is empty. Depends on how the client code uses it. + * @return an Iterator. + */ + @Override + public Iterator iterator() + { + return new ListIterator<>() + { + private Node current = first; + + @Override + public boolean hasNext() { + return current != null; + } + + @Override + public E next() + { + E item = current.item; + current = current.next; + return null; + } + + @Override + public boolean hasPrevious() { + return false; + } + + @Override + public E previous() { + return null; + } + + @Override + public int nextIndex() { + return 0; + } + + @Override + public int previousIndex() { + return 0; + } + + @Override + public void remove() { + + } + + @Override + public void set(E item) { + + } + + @Override + public void add(E item) { + + } + }; + } + + /** + * O(n) at worst + * This function is linear at worst because it loops over + * all elements in the array. It could be Constant if the array + * is empty. + * @return String value representing the list + */ + @Override + public String toString() { + Node current = first; + String nodes = ""; + if (current != null) { + nodes += (current.item + ", "); + while (current.next != null) { + current = current.next; + nodes += (current.item); + if (current.next != null) { + nodes += ", "; + } + } + } + return "LinkedStack{" + + "(" + size + " left on stack) " + + nodes; + } +} diff --git a/src/abstractDataTypes/ResizingArrayStack.java b/src/abstractDataTypes/ResizingArrayStack.java new file mode 100644 index 0000000..352f468 --- /dev/null +++ b/src/abstractDataTypes/ResizingArrayStack.java @@ -0,0 +1,174 @@ +/** + * Toby Goetz + */ + +package abstractDataTypes; + +import interfaces.Stack; +import java.util.Arrays; +import java.util.Iterator; + +/** + * @author Book People + * @version 1.0 + * @param + */ +public class ResizingArrayStack implements Stack { + + private E[] arr; + private int size; + + /** + * Constructor to instantiate ResizingArrayStack + * 0(1) at worst because of a few assignments + */ + public ResizingArrayStack() + { + this.arr = (E[]) new Object[1]; + size = 0; + } + + /** + * Add an item to the stack. + * O(n) at worst + * O(1) at best + * This function is linear at worst because it utilizes + * resize() to resize the array which is linear. It is + * logarithmically constant, meaning that resize() is + * only called n^2 times + * @param item the item to be added + */ + @Override + public void push(E item) + { // Add item to the top of stack + if (size == arr.length) { + resize(2 * arr.length); + } + arr[size++] = item; + } + + /** + * Removes the most recently added item from the stack. + * O(n) at worst + * O(1) at best + * This function is linear at worst because it utilizes + * resize() to resize the array which is linear. It is + * logarithmically constant, meaning that resize() is + * only called n^2 times (math might be wrong) + * @return the item that was removed + */ + @Override + public E pop() + { // Remove item from top of Stack + E item = arr[--size]; + arr[size] = null; + if (size > 0 && size == arr.length/4) { + resize(arr.length/2); + } + return item; + } + + /** + * Returns the item at the top of the stack. + * Does not modify the stack or the item at the top. + * O(1) at worst + * This function is constant because it accesses an + * element in an array + * @return item at the top of the stack. + */ + @Override + public E peek() { + return arr[size - 1]; + } + + /** + * Checks to see if the stack is empty. + * O(1) at worst + * This function is constant because it acceses an + * instance variable and returns a boolean value + * @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. + * O(1) at worst + * This function is constant at worst because it + * only accesses an instance variable + * @return the number of items in the stack + */ + @Override + public int size() { + return size; + } + + /** + * Returns an iterator over elements of type {@code T}. + * O(n) at worst + * This function is linear at worst because it loops over + * all elements in the array. It could be Constant if the array + * is empty. Depends on how the client code uses it. + * @return an Iterator. + */ + @Override + public Iterator iterator() + { + return new ReverseArrayIterator(); + } + + private class ReverseArrayIterator implements Iterator + { // Support LIFO iteration + private int current = size; + @Override + public boolean hasNext() { + return current > 0; + } + @Override + public E next() { + return arr[--current]; + } + @Override + public void remove() {} + + @Override + public String toString() { + return "ReverseArrayIterator{" + + "i=" + current + + '}'; + } + } + + /** + * Resizes the instance Array arr + * O(n) at worst + * This function is linear at worst because it loops over + * all elements in the array. It could be Constant if the array + * is empty. + * @param newLength initializes the Array arr to newLength size + */ + private void resize(int newLength) + { //Move stack to a new array of size newLength + E[] temp = (E[]) new Object[newLength]; + for (int i = 0; i < size; i++) { + temp[i] = arr[i]; + } + arr = temp; + } + + /** + * O(n) at worst + * This function is linear at worst because it loops over + * all elements in the array. It could be Constant if the array + * is empty. + * @return String value representing the list + */ + @Override + public String toString() { + return "ResizingArrayStack{ " + + "(" + size + " left on stack) " + + Arrays.toString(arr) + " }"; + } +} diff --git a/src/driver/QueueTestClient.java b/src/driver/QueueTestClient.java new file mode 100644 index 0000000..a4fd33d --- /dev/null +++ b/src/driver/QueueTestClient.java @@ -0,0 +1,39 @@ +/** + * Toby Goetz + */ + +package driver; + +import abstractDataTypes.LinkedQueue; +import java.util.Scanner; + +/** + * @author Book People + * @version 1.0 + */ +public class QueueTestClient +{ + public static final String SHAKESPREARE = "to be or not to - be - - that - - - is"; + + public static void main(String[] args) + { // Create a queue and enqueue/dequeue strings. + LinkedQueue linkedQueue = new LinkedQueue(); + Scanner in = new Scanner(SHAKESPREARE); + String poppedValues = ""; + + System.out.println("LinkedQueue:::Trace"); + System.out.println("-------------------"); + + while (in.hasNext()) { + String item = in.next(); + if (!item.equals("-")) { + linkedQueue.enqueue(item); + } + else if (!linkedQueue.isEmpty()) { + poppedValues += linkedQueue.dequeue() + " "; + } + System.out.println("(" + linkedQueue); + } + System.out.println("\n" + poppedValues + " (" + linkedQueue.size() + " left on stack)"); + } +} diff --git a/src/driver/StackTestClient.java b/src/driver/StackTestClient.java new file mode 100644 index 0000000..a2363ef --- /dev/null +++ b/src/driver/StackTestClient.java @@ -0,0 +1,64 @@ +/** + * Toby Goetz + */ + +package driver; +import abstractDataTypes.LinkedStack; +import abstractDataTypes.ResizingArrayStack; +import interfaces.Stack; + +import java.util.Scanner; + +/** + * @author Book People + * @version 1.0 + */ +public class StackTestClient { + + public static final String SHAKESPREARE = "to be or not to - be - - that - - - is"; + + public static void main(String[] args) + { + String poppedValues = ""; + + System.out.println("ResizingArrayStack:::Trace"); + System.out.println("--------------------------"); + + Stack arrayStack = new ResizingArrayStack(); + Scanner in = new Scanner(SHAKESPREARE); + + while (in.hasNext()) { + String item = in.next(); + if (!item.equals("-")) { + arrayStack.push(item); + } + else if (!arrayStack.isEmpty()) { + poppedValues += arrayStack.pop() + " "; + } + System.out.println("(" + arrayStack); + } + System.out.println("\n" + poppedValues + " (" + arrayStack.size() + " left on stack)"); + + + + poppedValues = ""; + System.out.println("\n \nLinkedStack:::Trace"); + System.out.println("---------------------"); + + Stack linkedStack = new LinkedStack(); + in = new Scanner(SHAKESPREARE); + + while (in.hasNext()) { + String item = in.next(); + if (!item.equals("-")) { + linkedStack.push(item); + } + else if (!linkedStack.isEmpty()) { + poppedValues += linkedStack.pop() + " "; + } + System.out.println("(" + linkedStack); + } + System.out.println("\n" + poppedValues + " (" + linkedStack.size() + " left on stack)"); + + } +} diff --git a/src/driver/Stats.java b/src/driver/Stats.java new file mode 100644 index 0000000..883e326 --- /dev/null +++ b/src/driver/Stats.java @@ -0,0 +1,37 @@ +/** + * Toby Goetz + */ + +package driver; +import abstractDataTypes.LinkedBag; +import java.util.Scanner; + +public class Stats +{ + public static void main(String[] args) + { + Scanner in = new Scanner("100 99 101 120 98 107 109 81 101 90"); + LinkedBag bagOfNumbers = new LinkedBag<>(); + + while (in.hasNext()) { + bagOfNumbers.add(in.nextDouble()); + } + int bagSize = bagOfNumbers.size(); + double sum = 0.0; + + for (double x : bagOfNumbers) { + sum += x; + } + double mean = sum/bagSize; + sum = 0.0; + + for (double x : bagOfNumbers) { + sum += (x - mean) * (x - mean); + } + double std = Math.sqrt(sum/(bagSize-1)); + + System.out.println(bagOfNumbers); + System.out.printf("Mean: %.2f\n", mean); + System.out.printf("Std dev: %.2f\n", std); + } +} diff --git a/src/interfaces/Bag.java b/src/interfaces/Bag.java new file mode 100644 index 0000000..3a03166 --- /dev/null +++ b/src/interfaces/Bag.java @@ -0,0 +1,27 @@ +package interfaces; + +/** + * interfaces.Bag (API / abstract data type) + * @param Class or data type of the items in the list + * @author unknown + * @version 1.0 + */ +public interface Bag extends Iterable { + + /** + * Add item to the Bag + * @param item the item to be added + */ + void add(E item); + /** + * Checks if the list is empty. + * @return true if the list is empty, false otherwise + */ + boolean isEmpty(); + /** + * Provides a count of the number of items in the list. + * @return number of items in the list + */ + int size(); + +}