diff --git a/DIRECTORY.md b/DIRECTORY.md index 31f46916e..b7e9e3b87 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -871,6 +871,7 @@ * [TokenBucketTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/queues/TokenBucketTest.java) * stacks * [NodeStackTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/stacks/NodeStackTest.java) + * [ReverseStackTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/stacks/ReverseStackTest.java) * [StackArrayListTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/stacks/StackArrayListTest.java) * [StackArrayTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/stacks/StackArrayTest.java) * [StackOfLinkedListTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/stacks/StackOfLinkedListTest.java) diff --git a/src/main/java/com/thealgorithms/datastructures/stacks/ReverseStack.java b/src/main/java/com/thealgorithms/datastructures/stacks/ReverseStack.java index 84e9df96e..e9de14b53 100644 --- a/src/main/java/com/thealgorithms/datastructures/stacks/ReverseStack.java +++ b/src/main/java/com/thealgorithms/datastructures/stacks/ReverseStack.java @@ -1,10 +1,25 @@ package com.thealgorithms.datastructures.stacks; -import java.util.Scanner; import java.util.Stack; /** - * Reversal of a stack using recursion. + * Provides methods to reverse a stack using recursion. + * + *

This class includes methods to reverse the order of elements in a stack + * without using additional data structures. Elements are inserted at the bottom + * of the stack to achieve the reverse order. + * + *

Example usage: + *

+ *     Stack stack = new Stack<>();
+ *     stack.push(1);
+ *     stack.push(2);
+ *     stack.push(3);
+ *     ReverseStack.reverseStack(stack);
+ * 
+ * After calling {@code reverseStack(stack)}, the stack's order is reversed. + * + *

This class is final and has a private constructor to prevent instantiation. * * @author Ishika Agarwal, 2021 */ @@ -12,56 +27,48 @@ public final class ReverseStack { private ReverseStack() { } - public static void main(String[] args) { - try (Scanner sc = new Scanner(System.in)) { - System.out.println("Enter the number of elements you wish to insert in the stack"); - int n = sc.nextInt(); - int i; - Stack stack = new Stack(); - System.out.println("Enter the stack elements"); - for (i = 0; i < n; i++) { - stack.push(sc.nextInt()); - } - reverseStack(stack); - System.out.println("The reversed stack is:"); - while (!stack.isEmpty()) { - System.out.print(stack.peek() + ","); - stack.pop(); - } - } - } - - private static void reverseStack(Stack stack) { + /** + * Reverses the order of elements in the given stack using recursion. + * Steps: + * 1. Check if the stack is empty. If so, return. + * 2. Pop the top element from the stack. + * 3. Recursively reverse the remaining stack. + * 4. Insert the originally popped element at the bottom of the reversed stack. + * + * @param stack the stack to reverse; should not be null + */ + public static void reverseStack(Stack stack) { if (stack.isEmpty()) { return; } - // Store the topmost element - int element = stack.peek(); - // Remove the topmost element - stack.pop(); - - // Reverse the stack for the leftover elements + int element = stack.pop(); reverseStack(stack); - - // Insert the topmost element to the bottom of the stack insertAtBottom(stack, element); } + /** + * Inserts the specified element at the bottom of the stack. + * + *

This method is a helper for {@link #reverseStack(Stack)}. + * + * Steps: + * 1. If the stack is empty, push the element and return. + * 2. Remove the top element from the stack. + * 3. Recursively insert the new element at the bottom of the stack. + * 4. Push the removed element back onto the stack. + * + * @param stack the stack in which to insert the element; should not be null + * @param element the element to insert at the bottom of the stack + */ private static void insertAtBottom(Stack stack, int element) { if (stack.isEmpty()) { - // When stack is empty, insert the element so it will be present at - // the bottom of the stack stack.push(element); return; } - int ele = stack.peek(); - // Keep popping elements till stack becomes empty. Push the elements - // once the topmost element has moved to the bottom of the stack. - stack.pop(); + int topElement = stack.pop(); insertAtBottom(stack, element); - - stack.push(ele); + stack.push(topElement); } } diff --git a/src/test/java/com/thealgorithms/datastructures/stacks/ReverseStackTest.java b/src/test/java/com/thealgorithms/datastructures/stacks/ReverseStackTest.java new file mode 100644 index 000000000..2e2bc5ada --- /dev/null +++ b/src/test/java/com/thealgorithms/datastructures/stacks/ReverseStackTest.java @@ -0,0 +1,70 @@ +package com.thealgorithms.datastructures.stacks; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.Stack; +import org.junit.jupiter.api.Test; + +class ReverseStackTest { + + @Test + void testReverseEmptyStack() { + Stack stack = new Stack<>(); + ReverseStack.reverseStack(stack); + assertTrue(stack.isEmpty(), "Reversing an empty stack should result in an empty stack."); + } + + @Test + void testReverseSingleElementStack() { + Stack stack = new Stack<>(); + stack.push(1); + ReverseStack.reverseStack(stack); + assertEquals(1, stack.peek(), "Reversing a single-element stack should have the same element on top."); + } + + @Test + void testReverseTwoElementStack() { + Stack stack = new Stack<>(); + stack.push(1); + stack.push(2); + ReverseStack.reverseStack(stack); + + assertEquals(1, stack.pop(), "After reversal, the stack's top element should be the first inserted element."); + assertEquals(2, stack.pop(), "After reversal, the stack's next element should be the second inserted element."); + } + + @Test + void testReverseMultipleElementsStack() { + Stack stack = new Stack<>(); + stack.push(1); + stack.push(2); + stack.push(3); + stack.push(4); + + ReverseStack.reverseStack(stack); + + assertEquals(1, stack.pop(), "Stack order after reversal should match the initial push order."); + assertEquals(2, stack.pop()); + assertEquals(3, stack.pop()); + assertEquals(4, stack.pop()); + } + + @Test + void testReverseStackAndVerifySize() { + Stack stack = new Stack<>(); + stack.push(10); + stack.push(20); + stack.push(30); + stack.push(40); + int originalSize = stack.size(); + + ReverseStack.reverseStack(stack); + + assertEquals(originalSize, stack.size(), "Stack size should remain unchanged after reversal."); + assertEquals(10, stack.pop(), "Reversal should place the first inserted element on top."); + assertEquals(20, stack.pop()); + assertEquals(30, stack.pop()); + assertEquals(40, stack.pop()); + } +}