diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..997def5 --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,297 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index 6f29fee..5af9c98 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,4 +1,3 @@ - diff --git a/.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/SDEV333-Term-Project.iml b/SDEV333-Term-Project.iml index c90834f..9c8bf10 100644 --- a/SDEV333-Term-Project.iml +++ b/SDEV333-Term-Project.iml @@ -4,8 +4,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/ArrayList.java b/src/ArrayList.java new file mode 100644 index 0000000..08673f7 --- /dev/null +++ b/src/ArrayList.java @@ -0,0 +1,306 @@ +import java.util.Iterator; +import java.util.NoSuchElementException; + +/** + * A generic implementation of an array list + * @param generic type + * @author Lois Lanctot + * @version 1.0 + */ +public class ArrayList implements List { + + private int size; + private E[] buffer; + + /** + * Constructor for an ArrayIntList object + * This method runs in O(1) or constant time in the worst case because + * regardless of the size of the array, the number of operations executed remains the same + */ + public ArrayList() { + size = 0; + this.buffer = (E[]) new Object[10]; + } + + + /** + * Add item to the front. + * This method runs in O(n) or linear time in the worst case + * because of the time needed to resize and shift elements + * @param item the item to be added + */ + @Override + public void addFront(E item) { + if (size == buffer.length) { + resize(size * 2); + } + + for (int i = size; i >= 1; i--) { + buffer[i] = buffer[i - 1]; + } + + buffer[0] = item; + size++; + } + + /** + * Add item to the back. + * This method runs in O(n) or linear time in the worst case because of the time needed to resize + * @param item the item to be added + */ + @Override + public void addBack(E item) { + if (size == buffer.length) { + resize(size * 2); + } + buffer[size] = item; + size++; + } + + /** + * Add an item at specified index (position). + * This method runs in O(n) or linear time in the worst case because of the time needed to resize and shift elements + * @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 && size == 0) { + size++; + } + else if (index < 0 || index > size) { + throw new IndexOutOfBoundsException("index is out of bounds"); + } + if (size == buffer.length) { + resize(size * 2); + } + + for (int j = size; j >= index; j--) { + buffer[j] = buffer[j - 1]; + } + + buffer[index] = item; + size++; + } + + /** + * Get the item at a specified index. + * This method runs in O(1) or constant time in the worst case because + * regardless of the size of the array, the number of operations executed remains the same + * @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 >= size) { + throw new IndexOutOfBoundsException("Index cannot be greater than size"); + } + else if (index < 0) { + throw new IndexOutOfBoundsException("Index cannot be less than zero"); + } + return buffer[index]; + } + + /** + * Set (save) an item at a specified index. Previous + * item at that index is overwritten. + * This method runs in O(1) or constant time in the worst case because + * regardless of the size of the array, the number of operations executed remains the same + * @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 is out of bounds + if (index <= 0 || index > size) { + throw new IndexOutOfBoundsException("index is out of bounds"); + } + + buffer[index] = item; + } + + /** + * Remove item at the front of the list. + * This method runs in O(n) or linear time in the worst case because of the time needed to shift elements + * + * @return the item that was removed + */ + @Override + public E removeFront() { + if (size != 0) { + + E frontItem = null; + for (int i = 0; i <= size; i++) { + frontItem = buffer[i]; + buffer[i] = buffer[i+1]; + } + size--; + return frontItem; + } + return null; + } + + /** + * Remove item at the back of the list + * This method runs in O(1) or constant time in the worst case because + * regardless of the size of the array, the number of operations executed remains the same + * @return the item that was removed + */ + @Override + public E removeBack() { + if (size != 0) { + E frontItem = buffer[size]; + buffer[size] = null; + size--; + return frontItem; + } + return null; + } + + /** + * Remove item from the list + * This method runs in O(n) or linear time in the worst case because of the time needed to shift elements + * @param item the item to be removed + */ + @Override + public void remove(E item) { + for (int i = 0; i < size; i++) { + if (buffer[i] == item) { + buffer[i] = buffer[i+1]; + size--; + } + } + + } + + /** + * Remove item at a specified index. + * This method runs in O(n) or linear time in the worst case because of the time needed to shift elements + * @param index the index where the item should be removed + * @return the item that was removed + */ + @Override + public E remove(int index) { + //validate index + if (index >= size) { + throw new IndexOutOfBoundsException("Index cannot be greater than size"); + } + else if (index < 0) { + throw new IndexOutOfBoundsException("Index cannot be less than zero"); + } + + E copyOfRemovedValue = buffer[index]; + + for (int j = index; j <= size - 1; j++) { + buffer[j] = buffer[j + 1]; + } + + buffer[size - 1] = null; + + size--; + + return copyOfRemovedValue; + } + + /** + * Checks if an item is in the list. + * This method runs in O(n) or linear time in the worst case because if + * the item is at the end you'd need to search through all the elements in the list + * @param item the item to search for + * @return true if the item is in the list, false otherwise + */ + @Override + public boolean contains(E item) { + for (int i = 0; i < size; i++) { + if (buffer[i] == item) { + return true; + } + } + return false; + } + + /** + * Checks if the list is empty. + * This method runs in O(1) or constant time in the worst case because + * regardless of the size of the array, the number of operations executed remains the same + * @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. + * This method runs in O(1) or constant time in the worst case because + * regardless of the size of the array, the number of operations executed remains the same + * @return number of items in the list + */ + @Override + public int size() { + return size; + } + + + private void resize(int newSize) { + //create new space, separate from the old space + E[] newBuffer = (E[]) new Object[newSize]; + + //copy everything over from buffer into newBuffer + for (int i = 0; i < buffer.length; i++) { + newBuffer[i] = buffer[i]; + } + buffer = newBuffer; + + } + + /** + * Returns an iterator over elements of type {@code E}. + * This method runs in O(1) or constant time in the worst case because + * regardless of the size of the array, the number of operations executed remains the same + * @return an Iterator. + */ + @Override + public Iterator iterator() { + return new ArrayListIterator(); + } + + private class ArrayListIterator implements Iterator { + //private fields + private int index; + + private ArrayListIterator() { + index = 0; + } + + /** + * Returns true if the iteration has more elements. + * + * @return 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("i is now out of bounds"); + } + + E currentValue = buffer[index]; + index++; + + return currentValue; + } + } + + +} diff --git a/src/Bag.java b/src/Bag.java new file mode 100644 index 0000000..9f9f9f6 --- /dev/null +++ b/src/Bag.java @@ -0,0 +1,23 @@ +/** + * Bag API + * @param class / data type of the items in the stack + */ +public interface Bag extends Iterable { + /** + * Add an item to the bag. + * @param item the item to be added + */ + void add(E item); + + /** + * Checks to see if the bag is empty. + * @return true if the bag is empty, false otherwise + */ + boolean isEmpty(); + + /** + * Returns a count of the number of items in the bag. + * @return the number of items in the bag + */ + int size(); +} diff --git a/src/LinkedBag.java b/src/LinkedBag.java new file mode 100644 index 0000000..e8c2fa7 --- /dev/null +++ b/src/LinkedBag.java @@ -0,0 +1,101 @@ +import java.util.Iterator; + + +/** + * A generic implementation of a linked bag + * @param generic type + * @author Lois Lanctot + * @version 1.0 + */ +public class LinkedBag implements Bag { + + private Node head; + private int size; + + private class Node { + E item; + Node next; + } + + /** + * Add an item to the bag. + * This method runs in O(1) or constant time in the worst case because + * regardless of the size of the array, the number of operations executed remains the same + * @param item the item to be added + */ + @Override + public void add(E item) { + Node oldHead = head; + head = new Node(); + head.item = item; + head.next = oldHead; + size++; + } + + /** + * Checks to see if the bag is empty. + * This method runs in O(1) or constant time in the worst case because + * regardless of the size of the array, the number of operations executed remains the same + * @return true if the bag is empty, false otherwise + */ + @Override + public boolean isEmpty() { + return head == null; + } + + /** + * Returns a count of the number of items in the bag. + * This method runs in O(1) or constant time in the worst case because + * regardless of the size of the array, the number of operations executed remains the same + * @return the number of items in the bag + */ + @Override + public int size() { + return size; + } + + /** + * Returns an iterator over elements of type {@code T}. + * This method runs in O(1) or constant time in the worst case because + * regardless of the size of the array, the number of operations executed remains the same + * @return an Iterator. + */ + @Override + public Iterator iterator() { + return new LinkedBag.ListIterator(); + } + + private class ListIterator implements Iterator { + + private LinkedBag.Node current; + + public ListIterator() { + this.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 + */ + @Override + public E next() { + E item = (E) current.item; + current = current.next; + return item; + } + } +} diff --git a/src/LinkedList.java b/src/LinkedList.java new file mode 100644 index 0000000..ff401f5 --- /dev/null +++ b/src/LinkedList.java @@ -0,0 +1,359 @@ +import java.util.Iterator; +import java.util.NoSuchElementException; + +/** + * A generic implementation of a linked list + * @param generic type + * @author Lois Lanctot + * @version 1.0 + */ +public class LinkedList implements List { + + //define what a Node is + private class Node { + E data; + Node next; + } + + private Node head; + private int size; + + /** + * constructor for the LinkedList + * This method runs in O(1) or constant time in the worst case because + * regardless of the size of the array, the number of operations executed remains the same + */ + public LinkedList() { + head = null; + size = 0; + } + + /** + * Add item to the front. + * This method runs in O(1) or constant time in the worst case because + * regardless of the size of the array, the number of operations executed remains the same + * @param item the item to be added + */ + @Override + public void addFront(E item) { + //set up a new node + Node theNewOne = new Node(); + theNewOne.data = item; + + if (head != null) { + //the list currently has some nodes in it + theNewOne.next = head; + } + head = theNewOne; + + size++; + } + + /** + * Add item to the back. + * This method runs in O(n) or linear time in the worst case because of the time it takes to traverse the nodes + * @param item the item to be added + */ + @Override + public void addBack(E item) { + Node theNewOne = new Node(); + theNewOne.data = item; + Node current = head; + + if (head == null) { + head = theNewOne; + } + else { + while (current.next != null) { + current = current.next; + } + current.next = theNewOne; + } + size++; + } + + /** + * Add an item at specified index (position). + * This method runs in O(n) or linear time in the worst case because of the time it takes to traverse the nodes + * @param index the specified index + * @param item the item to be added + */ + @Override + public void add(int index, E item) { + + if (index < 0 || index > size) { + throw new IndexOutOfBoundsException("Index is out of bounds"); + } + else { + Node theNewOne = new Node(); + theNewOne.data = item; + Node current = head; + + if (size == 0) { + head = theNewOne; + } + else { + while (index != 0) { + if (index != 1) { + current = current.next; + } + index--; + } + + if (current.next == null) { + addBack(item); + } + else { + theNewOne.next = current.next; + current.next = theNewOne; + } + } + + size++; + } + + } + + /** + * Get the item at a specified index. + * This method runs in O(n) or linear time in the worst case because of the time it takes to traverse the nodes + * @param index the index where the item should be retrieved + * @return the item located at that index + */ + @Override + public E get(int index) { + Node current = head; + index++; + if (index < 0 || index > size) { + throw new IndexOutOfBoundsException("Index out of bounds"); + } + else { + while (index != 1) { + current = current.next; + index--; + } + return current.data; + } + } + + /** + * Set (save) an item at a specified index. Previous + * item at that index is overwritten. + * This method runs in O(n) or linear time in the worst case because of the time it takes to traverse the nodes + * @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 is out of bounds + if (index < 0 || index >= size) { + throw new IndexOutOfBoundsException("Index is out of bounds"); + } + Node current = head; + + for (int j = 0; j < index; j++) { + current = current.next; + } + + current.data = item; + } + + + /** + * Remove item at the front of the list. + * This method runs in O(1) or constant time in the worst case because + * regardless of the size of the array, the number of operations executed remains the same + * @return the item that was removed + */ + @Override + public E removeFront() { + if (head != null) { + E removedData = head.data; + head = head.next; + size--; + return removedData; + } + + throw new IndexOutOfBoundsException("Index is out of bounds"); + } + + /** + * Remove item at the back of the list + * item at that index is overwritten. + * This method runs in O(n) or linear time in the worst case because of the time it takes to traverse the nodes + * @return the item that was removed + */ + @Override + public E removeBack() { + Node current = head; + + if (current != null) { + if (current.next != null && current.next.next != null) { + while (current.next.next != null) { + current = current.next; + } + } + E removedData = current.data; + current.next = null; + size--; + return removedData; + } + throw new IndexOutOfBoundsException("Index is out of bounds"); + + } + + /** + * Remove item from the list + * item at that index is overwritten. + * This method runs in O(n) or linear time in the worst case because of the time it takes to traverse the nodes + * @param item the item to be removed + */ + @Override + public void remove(E item) { + Node current = head; + + while (current.next != null) { + if (current.data == item) { + current = current.next; + } + + current = current.next; + } + size--; + + } + + /** + * Remove item at a specified index. + * This method runs in O(n) or linear time in the worst case because of the time it takes to traverse the nodes + * @param index the index where the item should be removed + * @return the item that was removed + */ + @Override + public E remove(int index) { + //validate index + if (index < 0 || index >= size) { + throw new IndexOutOfBoundsException("Index out of bounds"); + } + + Node current = head; + + // if the index is the first element + if (index == 0) { + E value = head.data; + head = head.next; + size--; + return value; + } + + for (int j = 0; j < index - 1; j++) { + current = current.next; + } + + E value = current.next.data; + + if (current.next.next != null) { + current.next = current.next.next; + } + else { + current.next = null; + } + + size--; + return value; + } + + /** + * Checks if an item is in the list. + * This method runs in O(n) or linear time in the worst case because of the time it takes to traverse the nodes + * @param item the item to search for + * @return true if the item is in the list, false otherwise + */ + @Override + public boolean contains(E item) { + Node current = head; + + if (current != null) { + if (current.next != null) { + while (current.next != null) { + if (current.data == item) { + return true; + } + current = current.next; + } + } + return current.data == item; + } + + return false; + } + + /** + * Checks if the list is empty. + * This method runs in O(1) or constant time in the worst case because + * regardless of the size of the array, the number of operations executed remains the same + * @return true if the list is empty, false otherwise + */ + @Override + public boolean isEmpty() { + return head == null; + } + + /** + * Provides a count of the number of items in the list. + * This method runs in O(1) or constant time in the worst case because + * regardless of the size of the array, the number of operations executed remains the same + * @return number of items in the list + */ + @Override + public int size() { + return size; + } + + /** + * Returns an iterator over elements of type {@code T}. + * This method runs in O(1) or constant time in the worst case because + * regardless of the size of the array, the number of operations executed remains the same + * @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() { + E item = current.data; + current = current.next; + return item; + } + } +} diff --git a/src/LinkedQueue.java b/src/LinkedQueue.java new file mode 100644 index 0000000..21db529 --- /dev/null +++ b/src/LinkedQueue.java @@ -0,0 +1,124 @@ +import java.util.Iterator; + +/** + * A generic implementation of a linked queue + * @param generic type + * @author Lois Lanctot + * @version 1.0 + */ +public class LinkedQueue implements Queue { + + private Node head; + private Node tail; + private int size; + + private class Node { + E item; + Node next; + } + + /** + * Add an item to the queue. + * This method runs in O(1) or constant time in the worst case because + * regardless of the size of the array, the number of operations executed remains the same + * @param item the item to be added + */ + @Override + public void enqueue(E item) { + Node oldLast = tail; + tail = new Node(); + tail.item = item; + tail.next = null; + if (isEmpty()) { + head = tail; + } + else { + oldLast.next = tail; + } + size++; + } + + /** + * Remove an item from the queue. + * This method runs in O(1) or constant time in the worst case because + * regardless of the size of the array, the number of operations executed remains the same + * @return the item that was removed + */ + @Override + public E dequeue() { + E item = head.item; + head = head.next; + size--; + if (isEmpty()) { + tail = null; + } + return item; + } + + /** + * Checks to see if the queue is empty. + * This method runs in O(1) or constant time in the worst case because + * regardless of the size of the array, the number of operations executed remains the same + * @return true if the queue is empty, false otherwise + */ + @Override + public boolean isEmpty() { + return head == null; + } + + /** + * Returns a count of the number of items in the queue. + * This method runs in O(1) or constant time in the worst case because + * regardless of the size of the array, the number of operations executed remains the same + * @return the number of items in the queue + */ + @Override + public int size() { + return size; + } + + /** + * Returns an iterator over elements of type {@code T}. + * This method runs in O(1) or constant time in the worst case because + * regardless of the size of the array, the number of operations executed remains the same + * @return an Iterator. + */ + @Override + public Iterator iterator() { + return new LinkedQueue.ListIterator(); + } + + private class ListIterator implements Iterator { + + private LinkedQueue.Node current; + + public ListIterator() { + this.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 + */ + @Override + public E next() { + E item = (E) current.item; + current = current.next; + return item; + } + } +} diff --git a/src/LinkedStack.java b/src/LinkedStack.java new file mode 100644 index 0000000..1840502 --- /dev/null +++ b/src/LinkedStack.java @@ -0,0 +1,126 @@ +import java.util.Iterator; + +/** + * A generic implementation of a linked stack + * @param generic type + * @author Lois Lanctot + * @version 1.0 + */ +public class LinkedStack implements Stack { + + private Node head; + private int size; + + private class Node { + E item; + Node next; + } + + /** + * Add an item to the stack. + * This method runs in O(1) or constant time in the worst case because + * regardless of the size of the array, the number of operations executed remains the same + * @param item the item to be added + */ + @Override + public void push(E item) { + Node oldFirst = head; + head = new Node(); + head.item = item; + head.next = oldFirst; + size++; + } + + /** + * Removes the most recently added item from the stack. + * This method runs in O(1) or constant time in the worst case because + * regardless of the size of the array, the number of operations executed remains the same + * @return the item that was removed + */ + @Override + public E pop() { + E item = head.item; + head = head.next; + size--; + return item; + } + + /** + * Returns the item at the top of the stack. + * Does not modify the stack or the item at the top. + * This method runs in O(1) or constant time in the worst case because + * regardless of the size of the array, the number of operations executed remains the same + * @return item at the top of the stack. + */ + @Override + public E peek() { + return head.item; + } + + /** + * Checks to see if the stack is empty. + * This method runs in O(1) or constant time in the worst case because + * regardless of the size of the array, the number of operations executed remains the same + * @return true if the stack is empty, false otherwise + */ + @Override + public boolean isEmpty() { + return head == null; + } + + /** + * Returns a count of the number of items in the stack. + * This method runs in O(1) or constant time in the worst case because + * regardless of the size of the array, the number of operations executed remains the same + * @return the number of items in the stack + */ + @Override + public int size() { + return size; + } + + /** + * Returns an iterator over elements of type {@code T}. + * This method runs in O(1) or constant time in the worst case because + * regardless of the size of the array, the number of operations executed remains the same + * @return an Iterator. + */ + @Override + public Iterator iterator() { + return new ListIterator(); + } + + private class ListIterator implements Iterator { + + private Node current; + + public ListIterator() { + this.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 + */ + @Override + public E next() { + E item = current.item; + current = current.next; + return item; + } + } +} diff --git a/src/Main.java b/src/Main.java index 8f8f984..491ccbb 100644 --- a/src/Main.java +++ b/src/Main.java @@ -1,6 +1,13 @@ -//TIP To Run code, press or -// click the icon in the gutter. +/** + * main class for testing if the project forked properly + * @author Lois Lanctot + * @version 1.0 + */ public class Main { + /** + * prints a welcome message to the console + * @param args command line arguments passed to the program + */ public static void main(String[] args) { //TIP Press with your caret at the highlighted text // to see how IntelliJ IDEA suggests fixing it. diff --git a/src/QueueTestClient.java b/src/QueueTestClient.java new file mode 100644 index 0000000..420a10a --- /dev/null +++ b/src/QueueTestClient.java @@ -0,0 +1,31 @@ +import java.util.Scanner; + +/** + * A test for the linked queue + * @author Lois Lanctot + * @version 1.0 + */ +public class QueueTestClient { + + /** + * runs tests for the linked queue + * @param args command line arguments passed to the program + */ + public static void main(String[] args) { + Queue queue = new LinkedQueue<>(); + Scanner input = new Scanner("to be or not to - be - - that - - - is"); + + while (input.hasNext()) { + String item = input.next(); + if (!item.equals("-")) { + queue.enqueue(item); + } + else if (!queue.isEmpty()) { + System.out.println(queue.dequeue() + " "); + } + } + + System.out.println("(" + queue.size() + " left on the stack)"); + + } +} diff --git a/src/ResizingArrayStack.java b/src/ResizingArrayStack.java new file mode 100644 index 0000000..8bf9e36 --- /dev/null +++ b/src/ResizingArrayStack.java @@ -0,0 +1,132 @@ +import java.util.Iterator; + +/** + * A generic implementation of a resizing array stack + * @param generic type + * @author Lois Lanctot + * @version 1.0 + */ +public class ResizingArrayStack implements Stack { + + private E[] array; + private int size; + + + /** + * A constructor for the ResizingArrayStack class + * * This method runs in O(1) or constant time in the worst case because + * * regardless of the size of the array, the number of operations executed remains the same + */ + public ResizingArrayStack() { + this.array = (E[]) new Object[1]; + this.size = 0; + } + + /** + * Add an item to the stack. + * This method runs in O(n) or linear time in the worst case because of the potential need to resize + * @param item the item to be added + */ + @Override + public void push(E item) { + //add item to top of stack + if (size == array.length) { + resize(2*array.length); + } + System.out.println(item); + array[size] = item; + size++; + } + + /** + * Removes the most recently added item from the stack. + * This method runs in O(n) or linear time in the worst case + * because of the time it takes to loop through the array + * @return the item that was removed + */ + @Override + public E pop() { + //remove item from top of stack + size--; + E item = array[size]; + array[size] = null; //avoid loitering + if (size > 0 && size == array.length/4) { + resize(array.length/2); + } + return item; + } + + /** + * Returns the item at the top of the stack. + * Does not modify the stack or the item at the top. + * This method runs in O(1) or constant time in the worst case because + * regardless of the size of the array, the number of operations executed remains the same + * @return item at the top of the stack. + */ + @Override + public E peek() { + return array[size - 1]; + } + + /** + * Checks to see if the stack is empty. + * This method runs in O(1) or constant time in the worst case because + * regardless of the size of the array, the number of operations executed remains the same + * @return true if the stack is empty, false otherwise + */ + @Override + public boolean isEmpty() { + return size == 0; + } + + /** + * Returns a count of the number of items in the stack. + * This method runs in O(1) or constant time in the worst case because + * regardless of the size of the array, the number of operations executed remains the same + * @return the number of items in the stack + */ + @Override + public int size() { + return size; + } + + + private void resize(int max) { + //move stack to a new array of size max + E[] temp = (E[]) new Object[max]; + for (int i = 0; i < size; i++) { + temp[i] = array[i]; + } + array = temp; + } + + /** + * Returns an iterator over elements of type {@code T}. + * This method runs in O(1) or constant time in the worst case because + * regardless of the size of the array, the number of operations executed remains the same + * @return an Iterator. + */ + @Override + public Iterator iterator() { + return new ReverseArrayIterator(); + } + + private class ReverseArrayIterator implements Iterator { + //support LIFO iteration + private int iterator = size-1; + + + @Override + public boolean hasNext() { + return iterator >= 0; + } + + @Override + public E next() { + iterator--; + return array[iterator]; + } + + + } +} diff --git a/src/StackTestClient.java b/src/StackTestClient.java new file mode 100644 index 0000000..8cc560d --- /dev/null +++ b/src/StackTestClient.java @@ -0,0 +1,31 @@ +import java.util.Scanner; + +/** + * A test for the linked stack + * @author Lois Lanctot + * @version 1.0 + */ +public class StackTestClient { + + /** + * runs tests for the linked stack + * @param args command line arguments passed to the program + */ + public static void main(String[] args) { + Stack stack = new LinkedStack<>(); + Scanner input = new Scanner("to be or not to - be - - that - - - is"); + + while (input.hasNext()) { + String item = input.next(); + if (!item.equals("-")) { + stack.push(item); + } + else if (!stack.isEmpty()) { + System.out.println(stack.pop() + " "); + } + } + + System.out.println("(" + stack.size() + " left on the stack)"); + + } +} diff --git a/src/Stats.java b/src/Stats.java new file mode 100644 index 0000000..89db875 --- /dev/null +++ b/src/Stats.java @@ -0,0 +1,40 @@ +import java.util.Scanner; + +/** + * A test for the linked bag + * @author Lois Lanctot + * @version 1.0 + */ +public class Stats { + /** + * runs tests for the linked bag + * @param args command line arguments passed to the program + */ + public static void main(String[] args) { + Bag numbers = new LinkedBag<>(); + Scanner input = new Scanner("100 99 101 120 98 107 109 81 101 90"); + + while (input.hasNextDouble()) { + numbers.add(input.nextDouble()); + } + + int size = numbers.size(); + double sum = 0.0; + for (double num : numbers) { + sum += num; + } + double mean = sum/size; + sum = 0.0; + + for (double num : numbers) { + sum += (num - mean) * (num - mean); + } + double stddev = Math.sqrt(sum/(size-1)); + + System.out.printf("Mean: %.2f\n", mean); + System.out.printf("Stddev: %.2f\n", stddev); + } + + + +} diff --git a/tests/ArrayListTest.java b/tests/ArrayListTest.java new file mode 100644 index 0000000..111a708 --- /dev/null +++ b/tests/ArrayListTest.java @@ -0,0 +1,207 @@ +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.*; + +public class ArrayListTest { + + + @Test + void addFront() { + ArrayList array = new ArrayList<>(); + + for (int i = 0; i < 20; i++) { + array.addFront(i); + assertEquals(array.get(0), i); + } + + + } + + @Test + void addBack() { + ArrayList array = new ArrayList<>(); + + for (int i = 0; i < 20; i++) { + array.addBack(i); + assertEquals(array.get(array.size()-1), i); + } + + } + + @Test + void add() { + ArrayList array = new ArrayList<>(); + + assertThrows(IndexOutOfBoundsException.class, () -> array.add(0, 8)); + + for (int i = 1; i < 20; i++) { + array.add(i, i+1); + assertEquals(array.get(i), i+1); + } + + } + + @Test + void removeFront() { + ArrayList array = new ArrayList<>(); + + array.removeFront(); + assertEquals(array.size(), 0); + + array.addFront(6); + array.removeFront(); + assertEquals(array.size(), 0); + + array.addFront(0); + array.addFront(9); + array.removeFront(); + assertEquals(array.size(), 1); + + array.addFront(0); + array.addFront(9); + array.removeFront(); + assertEquals(array.size(), 2); + + } + + @Test + void removeBack() { + ArrayList array = new ArrayList<>(); + + array.removeBack(); + assertEquals(array.size(), 0); + + array.addFront(6); + array.removeBack(); + assertEquals(array.size(), 0); + + array.addFront(0); + array.addFront(9); + array.removeBack(); + assertEquals(array.size(), 1); + + array.addFront(0); + array.addFront(9); + array.removeBack(); + assertEquals(array.size(), 2); + + } + + @Test + void removeItem() { + ArrayList array = new ArrayList<>(); + + array.addFront("test1"); + array.remove("test1"); + assertEquals(array.size(), 0); + + array.addFront("test2"); + array.addFront("test3"); + array.remove("test3"); + assertEquals(array.size(), 1); + + array.addFront("test4"); + array.addFront("test5"); + array.remove("test4"); + assertEquals(array.size(), 2); + } + + + @Test + void removeIndex() { + ArrayList array = new ArrayList<>(); + + assertThrows(IndexOutOfBoundsException.class, () -> array.remove(0)); + + array.addFront("test1"); + array.remove(0); + assertEquals(array.size(), 0); + + array.addFront("test2"); + array.addFront("test3"); + array.remove(1); + assertEquals(array.size(), 1); + + array.addFront("test4"); + array.addFront("test5"); + array.remove(2); + assertEquals(array.size(), 2); + } + + + @Test + void get() { + ArrayList array = new ArrayList<>(); + + assertThrows(IndexOutOfBoundsException.class, () -> array.get(0)); + + for (int i = 0; i < 20; i++) { + array.addFront(i); + assertEquals(array.get(0), i); + } + } + + @Test + void set() { + ArrayList array = new ArrayList<>(); + assertThrows(IndexOutOfBoundsException.class, () -> array.set(0, 3)); + array.addFront(1); + + for (int i = 1; i < 10; i++) { + array.addFront(i); + } + + array.set(4, 7); + assertEquals(7, array.get(4)); + + + } + + @Test + void contains() { + ArrayList array = new ArrayList<>(); + + + assertFalse(array.contains(4)); + + array.addFront(3); + assertTrue(array.contains(3)); + assertFalse(array.contains(9)); + + + array.addFront(8); + assertTrue(array.contains(3)); + assertFalse(array.contains(0)); + + for (int i = 0; i < 4; i++) { + array.addFront(i); + } + assertTrue(array.contains(2)); + assertFalse(array.contains(100)); + } + + @Test + void isEmpty() { + ArrayList array = new ArrayList<>(); + + assertTrue(array.isEmpty()); + + for (int i = 0; i < 20; i++) { + array.addBack(i); + assertFalse(array.isEmpty()); + } + } + + @Test + void size() { + ArrayList array = new ArrayList<>(); + + assertEquals(array.size(), 0); + + for (int i = 1; i < 20; i++) { + array.addBack(i); + assertEquals(array.size(), i); + } + } + + +} diff --git a/tests/LinkedListTest.java b/tests/LinkedListTest.java new file mode 100644 index 0000000..449d08a --- /dev/null +++ b/tests/LinkedListTest.java @@ -0,0 +1,196 @@ +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +public class LinkedListTest { + + @Test + void addFront() { + LinkedList array = new LinkedList<>(); + + for (int i = 0; i < 20; i++) { + array.addFront(i); + assertEquals(array.get(0), i); + } + + } + + @Test + void addBack() { + LinkedList array = new LinkedList<>(); + + for (int i = 0; i < 20; i++) { + array.addBack(i); + assertEquals(array.get(array.size()-1), i); + } + + } + + @Test + void add() { + LinkedList array = new LinkedList<>(); + assertThrows(IndexOutOfBoundsException.class, () -> array.add(1, 8)); + + for (int i = 0; i < 20; i++) { + array.add(i, i+1); + assertEquals(array.get(i), i+1); + } + + } + + @Test + void removeFront() { + LinkedList array = new LinkedList<>(); + assertThrows(IndexOutOfBoundsException.class, () -> array.removeFront()); + assertEquals(array.size(), 0); + + array.addFront("test1"); + array.removeFront(); + assertEquals(array.size(), 0); + + array.addFront("test2"); + array.addFront("test3"); + array.removeFront(); + assertEquals(array.size(), 1); + + array.addFront("test4"); + array.addFront("test5"); + array.removeFront(); + assertEquals(array.size(), 2); + + } + + @Test + void removeBack() { + LinkedList array = new LinkedList<>(); + assertThrows(IndexOutOfBoundsException.class, () -> array.removeBack()); + assertEquals(array.size(), 0); + + array.addFront(6); + array.removeBack(); + assertEquals(0, array.size()); + + array.addFront(0); + array.addFront(9); + array.removeBack(); + assertEquals(1, array.size()); + + array.addFront(0); + array.addFront(9); + array.removeBack(); + assertEquals(2, array.size()); + + } + + @Test + void removeItem() { + LinkedList array = new LinkedList<>(); + + array.addFront("test1"); + array.remove("test1"); + assertEquals(array.size(), 0); + + array.addFront("test2"); + array.addFront("test3"); + array.remove("test3"); + assertEquals(array.size(), 1); + + array.addFront("test4"); + array.addFront("test5"); + array.remove("test4"); + assertEquals(array.size(), 2); + } + + @Test + void removeIndex() { + LinkedList array = new LinkedList<>(); + + assertThrows(IndexOutOfBoundsException.class, () -> array.remove(0)); + + array.addFront("test1"); + array.remove(0); + assertEquals(array.size(), 0); + + array.addFront("test2"); + array.addFront("test3"); + array.remove(1); + assertEquals(array.size(), 1); + + array.addFront("test4"); + array.addFront("test5"); + array.remove(2); + assertEquals(array.size(), 2); + } + + @Test + void get() { + LinkedList array = new LinkedList<>(); + assertThrows(IndexOutOfBoundsException.class, () -> array.get(0)); + + for (int i = 0; i < 20; i++) { + array.addFront(i); + assertEquals(array.get(0), i); + } + } + + @Test + void set() { + LinkedList array = new LinkedList<>(); + assertThrows(IndexOutOfBoundsException.class, () -> array.set(0, 3)); + array.addFront(1); + + for (int i = 1; i < 10; i++) { + array.addFront(i); + } + + array.set(4, 7); + assertEquals(7, array.get(4)); + + } + + @Test + void contains() { + LinkedList array = new LinkedList<>(); + + assertFalse(array.contains(4)); + + array.addFront(3); + assertTrue(array.contains(3)); + assertFalse(array.contains(9)); + + + array.addFront(8); + assertTrue(array.contains(3)); + assertFalse(array.contains(0)); + + for (int i = 0; i < 4; i++) { + array.addFront(i); + } + assertTrue(array.contains(2)); + assertFalse(array.contains(100)); + } + + @Test + void isEmpty() { + LinkedList array = new LinkedList<>(); + assertTrue(array.isEmpty()); + + for (int i = 0; i < 20; i++) { + array.addBack(i); + assertFalse(array.isEmpty()); + } + } + + @Test + void size() { + LinkedList array = new LinkedList<>(); + assertEquals(array.size(), 0); + + for (int i = 1; i < 20; i++) { + array.addBack(i); + assertEquals(array.size(), i); + } + } + + +}