diff --git a/Algorithms/LinkedListRecursive/src/main/java/adt/stack/Stack.java b/Algorithms/LinkedListRecursive/src/main/java/adt/stack/Stack.java new file mode 100644 index 000000000..09dace39a --- /dev/null +++ b/Algorithms/LinkedListRecursive/src/main/java/adt/stack/Stack.java @@ -0,0 +1,50 @@ +package adt.stack; + +/** + * The interface of a generic stack. The queue is able to store any kind of + * data. + * + */ +public interface Stack { + + /** + * Inserts a new element in the stack or returns an exception if the stack + * is full. Null elements are not allowed (the stack remains unchanged). + * + * @param element + * @throws StackOverflowException + */ + public void push(T element) throws StackOverflowException; + + /** + * If the stack has elements, it removes the top of the stack and returns + * it; otherwise, it returns an exception. + * + * @return + * @throws StackUnderflowException + */ + public T pop() throws StackUnderflowException; + + /** + * Returns (without removing) the top element of the stack or null if the + * stack is empty. + * + * @return + */ + public T top(); + + /** + * Returns true if the stack is empty or false, otherwise. + * + * @return + */ + public boolean isEmpty(); + + /** + * Returns true if the stack is full or false, otherwise. + * + * @return + */ + public boolean isFull(); + +} diff --git a/Algorithms/LinkedListRecursive/src/main/java/adt/stack/StackOverflowException.java b/Algorithms/LinkedListRecursive/src/main/java/adt/stack/StackOverflowException.java new file mode 100644 index 000000000..0d322ebfb --- /dev/null +++ b/Algorithms/LinkedListRecursive/src/main/java/adt/stack/StackOverflowException.java @@ -0,0 +1,9 @@ +package adt.stack; + +public class StackOverflowException extends Exception { + + public StackOverflowException() { + super("Stack is full"); + } + +} diff --git a/Algorithms/LinkedListRecursive/src/main/java/adt/stack/StackRecursiveDoubleLinkedListImpl.java b/Algorithms/LinkedListRecursive/src/main/java/adt/stack/StackRecursiveDoubleLinkedListImpl.java new file mode 100644 index 000000000..dc4dd7895 --- /dev/null +++ b/Algorithms/LinkedListRecursive/src/main/java/adt/stack/StackRecursiveDoubleLinkedListImpl.java @@ -0,0 +1,47 @@ +package adt.stack; + +import adt.linkedList.DoubleLinkedList; +import adt.linkedList.RecursiveDoubleLinkedListImpl; + +public class StackRecursiveDoubleLinkedListImpl implements Stack { + + protected DoubleLinkedList top; + protected int size; + + public StackRecursiveDoubleLinkedListImpl(int size) { + this.size = size; + this.top = new RecursiveDoubleLinkedListImpl(); + } + + @Override + public void push(T element) throws StackOverflowException { + if (isFull()) + throw new StackOverflowException(); + top.insertFirst(element); + } + + @Override + public T pop() throws StackUnderflowException { + if (isEmpty()) + throw new StackUnderflowException(); + T popped = top(); + top.removeFirst(); + return popped; + } + + @Override + public T top() { + return ((RecursiveDoubleLinkedListImpl) top).getData(); + } + + @Override + public boolean isEmpty() { + return top.isEmpty(); + } + + @Override + public boolean isFull() { + return top.size() == size; + } + +} \ No newline at end of file diff --git a/Algorithms/LinkedListRecursive/src/main/java/adt/stack/StackUnderflowException.java b/Algorithms/LinkedListRecursive/src/main/java/adt/stack/StackUnderflowException.java new file mode 100644 index 000000000..5a1973c62 --- /dev/null +++ b/Algorithms/LinkedListRecursive/src/main/java/adt/stack/StackUnderflowException.java @@ -0,0 +1,8 @@ +package adt.stack; + +public class StackUnderflowException extends Exception { + + public StackUnderflowException() { + super("Stack is empty"); + } +} diff --git a/Algorithms/LinkedListRecursive/src/main/java/adt/stack/linkedList/DoubleLinkedList.java b/Algorithms/LinkedListRecursive/src/main/java/adt/stack/linkedList/DoubleLinkedList.java new file mode 100644 index 000000000..4bcc55715 --- /dev/null +++ b/Algorithms/LinkedListRecursive/src/main/java/adt/stack/linkedList/DoubleLinkedList.java @@ -0,0 +1,29 @@ +package adt.linkedList; + +/** + * The interface of a double linked list with a head and a last (Deque). + * + * @param + */ +public interface DoubleLinkedList extends LinkedList { + + /** + * Inserts a new element in the first position (head) of the list. The + * "head" reference must be updated. + * + * @param element + */ + public void insertFirst(T element); + + /** + * Removes the first element (head) of the list. The "head" reference must + * be updated. + */ + public void removeFirst(); + + /** + * Removes the last element (last) of the list. The "last" reference must be + * updated. + */ + public void removeLast(); +} diff --git a/Algorithms/LinkedListRecursive/src/main/java/adt/stack/linkedList/LinkedList.java b/Algorithms/LinkedListRecursive/src/main/java/adt/stack/linkedList/LinkedList.java new file mode 100644 index 000000000..3cc2d3776 --- /dev/null +++ b/Algorithms/LinkedListRecursive/src/main/java/adt/stack/linkedList/LinkedList.java @@ -0,0 +1,53 @@ +package adt.linkedList; + +/** + * The interface of a generic linked list. + */ +public interface LinkedList { + /** + * @return true if the list is empty or false, otherwise + */ + public boolean isEmpty(); + + /** + * @return the number of elements on the list + */ + public int size(); + + /** + * Searches for a given element in the list. + * + * @param element + * the element being searched for + * @return the element if it is in the list or null, otherwise + */ + public T search(T element); + + /** + * Inserts a new element at the end of the list. Null elements must be + * ignored. + * + * @param element + * the element to be inserted + */ + public void insert(T element); + + /** + * Removes an element from the list. If the element does not exist the list + * is not changed. + * + * @param element + * the element to be removed + */ + public void remove(T element); + + /** + * Returns an array containing all elements in the structure. The array does + * not contain empty spaces (or null elements). The elements are put into + * the array from the beginning to the end of the list. + * + * @return an array containing all elements in the structure in the order + * they appear + */ + public T[] toArray(); +} \ No newline at end of file diff --git a/Algorithms/LinkedListRecursive/src/main/java/adt/stack/linkedList/RecursiveDoubleLinkedListImpl.java b/Algorithms/LinkedListRecursive/src/main/java/adt/stack/linkedList/RecursiveDoubleLinkedListImpl.java new file mode 100644 index 000000000..be0ff7793 --- /dev/null +++ b/Algorithms/LinkedListRecursive/src/main/java/adt/stack/linkedList/RecursiveDoubleLinkedListImpl.java @@ -0,0 +1,93 @@ +package adt.linkedList; + +public class RecursiveDoubleLinkedListImpl extends + RecursiveSingleLinkedListImpl implements DoubleLinkedList { + + protected RecursiveDoubleLinkedListImpl previous; + + public RecursiveDoubleLinkedListImpl() { + + } + + public RecursiveDoubleLinkedListImpl(T data, + RecursiveSingleLinkedListImpl next, + RecursiveDoubleLinkedListImpl previous) { + super(data, next); + this.previous = previous; + } + + @Override + public void insert(T element) { + if (element != null) { + if (isEmpty()) { + setData(element); + setNext(new RecursiveDoubleLinkedListImpl()); + ((RecursiveDoubleLinkedListImpl) getNext()).setPrevious(this); + if (getPrevious() == null) { + setPrevious(new RecursiveDoubleLinkedListImpl()); + getPrevious().setNext(this); + } + } else + getNext().insert(element); + } + } + + @Override + public void insertFirst(T element) { + if (element != null) { + if (isEmpty()) { + setData(element); + setPrevious(new RecursiveDoubleLinkedListImpl()); + getPrevious().setNext(this); + if (getNext() == null) { + setNext(new RecursiveDoubleLinkedListImpl()); + ((RecursiveDoubleLinkedListImpl) getNext()).setPrevious(this); + } else + tradeHead(((RecursiveDoubleLinkedListImpl) getNext()), this); + } else + getPrevious().insertFirst(element); + } + } + + private void tradeHead(RecursiveDoubleLinkedListImpl head, RecursiveDoubleLinkedListImpl newHead) { + T dataHead = head.getData(); + head.setData(newHead.getData()); + newHead.setData(dataHead); + newHead.setNext(head.getNext()); + head.setNext(newHead); + ((RecursiveDoubleLinkedListImpl) newHead.getNext()).setPrevious(newHead); + newHead.setPrevious(head); + head.setPrevious(new RecursiveDoubleLinkedListImpl()); + head.getPrevious().setNext(head); + } + + @Override + public void removeFirst() { + if (!isEmpty()) { + if (getPrevious().isEmpty()) { + setData(getNext().getData()); + setNext(getNext().getNext()); + } else + getPrevious().removeFirst(); + } + } + + @Override + public void removeLast() { + if (!isEmpty()) { + if (getNext().isEmpty()) { + setData(getNext().getData()); + setNext(getNext().getNext()); + } else + ((RecursiveDoubleLinkedListImpl) getNext()).removeLast(); + } + } + + public RecursiveDoubleLinkedListImpl getPrevious() { + return previous; + } + public void setPrevious(RecursiveDoubleLinkedListImpl previous) { + this.previous = previous; + } + +} \ No newline at end of file diff --git a/Algorithms/LinkedListRecursive/src/main/java/adt/stack/linkedList/RecursiveSingleLinkedListImpl.java b/Algorithms/LinkedListRecursive/src/main/java/adt/stack/linkedList/RecursiveSingleLinkedListImpl.java new file mode 100644 index 000000000..15d820c43 --- /dev/null +++ b/Algorithms/LinkedListRecursive/src/main/java/adt/stack/linkedList/RecursiveSingleLinkedListImpl.java @@ -0,0 +1,100 @@ +package adt.linkedList; + +public class RecursiveSingleLinkedListImpl implements LinkedList { + + protected T data; + protected RecursiveSingleLinkedListImpl next; + + public RecursiveSingleLinkedListImpl() { + + } + + public RecursiveSingleLinkedListImpl(T data, + RecursiveSingleLinkedListImpl next) { + this.data = data; + this.next = next; + } + + @Override + public boolean isEmpty() { + boolean empty = false; + if (getData() == null) + empty = true; + return empty; + + } + + @Override + public int size() { + int result = 0; + if (!isEmpty()) + result = 1 + getNext().size(); + return result; + } + + @Override + public T search(T element) { + T result = null; + if (!isEmpty() && element != null) { + if (getData().equals(element)) + result = getData(); + else + result = getNext().search(element); + } + return result; + } + + @Override + public void insert(T element) { + if (element != null) { + if (isEmpty()) { + setData(element); + setNext(new RecursiveSingleLinkedListImpl()); + } else + getNext().insert(element); + } + } + + @Override + public void remove(T element) { + if (!isEmpty() && element != null) { + if (getData().equals(element)) { + setData(getNext().getData()); + setNext(getNext().getNext()); + } else + getNext().remove(element); + } + } + + @Override + public T[] toArray() { + T[] result = (T[]) new Object[size()]; + toArray(result, this, 0); + return result; + } + + + private void toArray(T[] result, RecursiveSingleLinkedListImpl node, int index) { + if (!node.isEmpty()) { + result[index] = node.getData(); + toArray(result, node.getNext(), index + 1); + } + } + + public T getData() { + return data; + } + + public void setData(T data) { + this.data = data; + } + + public RecursiveSingleLinkedListImpl getNext() { + return next; + } + + public void setNext(RecursiveSingleLinkedListImpl next) { + this.next = next; + } + +} \ No newline at end of file diff --git a/Algorithms/LinkedListRecursive/src/test/java/adt/linkedList/StudentDoubleLinkedListTest.java b/Algorithms/LinkedListRecursive/src/test/java/adt/linkedList/StudentDoubleLinkedListTest.java new file mode 100644 index 000000000..ab03affc9 --- /dev/null +++ b/Algorithms/LinkedListRecursive/src/test/java/adt/linkedList/StudentDoubleLinkedListTest.java @@ -0,0 +1,51 @@ +package adt.linkedList; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +public class StudentDoubleLinkedListTest extends StudentLinkedListTest { + + private DoubleLinkedList lista3; + + @Before + public void setUp() throws Exception { + + getImplementations(); + + // Lista com 3 elementos. + lista1.insert(3); + lista1.insert(2); + lista1.insert(1); + + // Lista com 1 elemento. + lista3.insert(1); + } + + private void getImplementations() { + // TODO O aluno deve ajustar aqui para instanciar sua implementação + lista1 = new RecursiveDoubleLinkedListImpl<>(); + lista2 = new RecursiveDoubleLinkedListImpl<>(); + lista3 = new RecursiveDoubleLinkedListImpl<>(); + } + + // Métodos de DoubleLinkedList + + @Test + public void testInsertFirst() { + ((DoubleLinkedList) lista1).insertFirst(4); + Assert.assertArrayEquals(new Integer[] { 4, 3, 2, 1 }, lista1.toArray()); + } + + @Test + public void testRemoveFirst() { + ((DoubleLinkedList) lista1).removeFirst(); + Assert.assertArrayEquals(new Integer[] { 2, 1 }, lista1.toArray()); + } + + @Test + public void testRemoveLast() { + ((DoubleLinkedList) lista1).removeLast(); + Assert.assertArrayEquals(new Integer[] { 3, 2 }, lista1.toArray()); + } +} \ No newline at end of file diff --git a/Algorithms/LinkedListRecursive/src/test/java/adt/linkedList/StudentLinkedListTest.java b/Algorithms/LinkedListRecursive/src/test/java/adt/linkedList/StudentLinkedListTest.java new file mode 100644 index 000000000..a32fbd4d3 --- /dev/null +++ b/Algorithms/LinkedListRecursive/src/test/java/adt/linkedList/StudentLinkedListTest.java @@ -0,0 +1,76 @@ +package adt.linkedList; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +public class StudentLinkedListTest { + + protected LinkedList lista1; + protected LinkedList lista2; + + @Before + public void setUp() throws Exception { + + getImplementations(); + + // Lista com 3 elementos. + lista1.insert(3); + lista1.insert(2); + lista1.insert(1); + + } + + private void getImplementations() { + // TODO O aluno deve ajustar aqui para instanciar sua implementação + lista1 = new RecursiveSingleLinkedListImpl<>(); + lista2 = new RecursiveSingleLinkedListImpl<>(); + } + + @Test + public void testIsEmpty() { + Assert.assertFalse(lista1.isEmpty()); + Assert.assertTrue(lista2.isEmpty()); + } + + @Test + public void testSize() { + Assert.assertEquals(3, lista1.size()); + Assert.assertEquals(0, lista2.size()); + } + + @Test + public void testSearch() { + Assert.assertTrue(2 == lista1.search(2)); + Assert.assertNull(lista1.search(4)); + Assert.assertFalse(3 == lista1.search(2)); + } + + @Test + public void testInsert() { + Assert.assertEquals(3, lista1.size()); + lista1.insert(5); + lista1.insert(7); + Assert.assertEquals(5, lista1.size()); + + Assert.assertEquals(0, lista2.size()); + lista2.insert(4); + lista2.insert(7); + Assert.assertEquals(2, lista2.size()); + } + + @Test + public void testRemove() { + Assert.assertEquals(3, lista1.size()); + lista1.remove(2); + lista1.remove(1); + Assert.assertEquals(1, lista1.size()); + + } + + @Test + public void testToArray() { + Assert.assertArrayEquals(new Integer[] {}, lista2.toArray()); + Assert.assertArrayEquals(new Integer[] { 3, 2, 1 }, lista1.toArray()); + } +} \ No newline at end of file