From d3bd2874c83a0cb14c564f01d3e45c9b823f4960 Mon Sep 17 00:00:00 2001 From: Hardik Pawar <97388607+Hardvan@users.noreply.github.com> Date: Tue, 8 Oct 2024 23:07:10 +0530 Subject: [PATCH] Add StackUsingTwoQueues algorithm (#5625) --- DIRECTORY.md | 2 + .../stacks/StackUsingTwoQueues.java | 91 +++++++++++++++++++ .../stacks/StackUsingTwoQueuesTest.java | 70 ++++++++++++++ 3 files changed, 163 insertions(+) create mode 100644 src/main/java/com/thealgorithms/stacks/StackUsingTwoQueues.java create mode 100644 src/test/java/com/thealgorithms/stacks/StackUsingTwoQueuesTest.java diff --git a/DIRECTORY.md b/DIRECTORY.md index 9fb111292..7a1bb728f 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -569,6 +569,7 @@ * [PrefixToInfix](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/PrefixToInfix.java) * [SortStack](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/SortStack.java) * [StackPostfixNotation](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/StackPostfixNotation.java) + * [StackUsingTwoQueues](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/StackUsingTwoQueues.java) * strings * [AhoCorasick](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/strings/AhoCorasick.java) * [Alphabetical](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/strings/Alphabetical.java) @@ -1032,6 +1033,7 @@ * [PrefixToInfixTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/stacks/PrefixToInfixTest.java) * [SortStackTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/stacks/SortStackTest.java) * [StackPostfixNotationTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/stacks/StackPostfixNotationTest.java) + * [StackUsingTwoQueuesTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/stacks/StackUsingTwoQueuesTest.java) * strings * [AhoCorasickTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/strings/AhoCorasickTest.java) * [AlphabeticalTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/strings/AlphabeticalTest.java) diff --git a/src/main/java/com/thealgorithms/stacks/StackUsingTwoQueues.java b/src/main/java/com/thealgorithms/stacks/StackUsingTwoQueues.java new file mode 100644 index 000000000..5b1ca5d1d --- /dev/null +++ b/src/main/java/com/thealgorithms/stacks/StackUsingTwoQueues.java @@ -0,0 +1,91 @@ +package com.thealgorithms.stacks; + +import java.util.LinkedList; +import java.util.NoSuchElementException; +import java.util.Queue; + +/** + * A class that implements a stack using two queues. + * This approach ensures that the stack's LIFO (Last In, First Out) behavior + * is maintained by utilizing two queues for storage. + * The mainQueue is used to store the elements of the stack, while the tempQueue + * is used to temporarily store elements during the push operation. + */ +public class StackUsingTwoQueues { + + private Queue mainQueue; + private Queue tempQueue; + + /** + * Constructs an empty stack using two queues. + */ + public StackUsingTwoQueues() { + mainQueue = new LinkedList<>(); + tempQueue = new LinkedList<>(); + } + + /** + * Pushes an element onto the top of the stack. + * The newly pushed element becomes the top of the stack. + * + * @param item The element to be pushed onto the stack. + */ + public void push(int item) { + tempQueue.add(item); + + // Move all elements from the mainQueue to tempQueue to maintain LIFO order + while (!mainQueue.isEmpty()) { + tempQueue.add(mainQueue.remove()); + } + + // Swap the names of the two queues + Queue swap = mainQueue; + mainQueue = tempQueue; + tempQueue = swap; // tempQueue is now empty + } + + /** + * Removes and returns the element at the top of the stack. + * Throws an exception if the stack is empty. + * + * @return The element at the top of the stack. + * @throws NoSuchElementException if the stack is empty. + */ + public int pop() { + if (mainQueue.isEmpty()) { + throw new NoSuchElementException("Stack is empty"); + } + return mainQueue.remove(); + } + + /** + * Returns the element at the top of the stack without removing it. + * Returns null if the stack is empty. + * + * @return The element at the top of the stack, or null if the stack is empty. + */ + public Integer peek() { + if (mainQueue.isEmpty()) { + return null; + } + return mainQueue.peek(); + } + + /** + * Returns true if the stack is empty. + * + * @return true if the stack is empty; false otherwise. + */ + public boolean isEmpty() { + return mainQueue.isEmpty(); + } + + /** + * Returns the number of elements in the stack. + * + * @return The size of the stack. + */ + public int size() { + return mainQueue.size(); + } +} diff --git a/src/test/java/com/thealgorithms/stacks/StackUsingTwoQueuesTest.java b/src/test/java/com/thealgorithms/stacks/StackUsingTwoQueuesTest.java new file mode 100644 index 000000000..a7e24421e --- /dev/null +++ b/src/test/java/com/thealgorithms/stacks/StackUsingTwoQueuesTest.java @@ -0,0 +1,70 @@ +package com.thealgorithms.stacks; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +public class StackUsingTwoQueuesTest { + + private StackUsingTwoQueues stack; + + @BeforeEach + public void setUp() { + stack = new StackUsingTwoQueues(); + } + + @Test + public void testPushAndPeek() { + stack.push(1); + stack.push(2); + stack.push(3); + assertEquals(3, stack.peek()); + } + + @Test + public void testPop() { + stack.push(1); + stack.push(2); + stack.push(3); + assertEquals(3, stack.pop()); + assertEquals(2, stack.pop()); + assertEquals(1, stack.pop()); + } + + @Test + public void testPeek() { + stack.push(10); + stack.push(20); + assertEquals(20, stack.peek()); + stack.pop(); + assertEquals(10, stack.peek()); + } + + @Test + public void testIsEmpty() { + assertTrue(stack.isEmpty()); + stack.push(1); + assertFalse(stack.isEmpty()); + stack.pop(); + assertTrue(stack.isEmpty()); + } + + @Test + public void testSize() { + assertEquals(0, stack.size()); + stack.push(1); + stack.push(2); + assertEquals(2, stack.size()); + stack.pop(); + assertEquals(1, stack.size()); + } + + @Test + public void testPeekEmptyStack() { + assertNull(stack.peek()); + } +}