Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions DIRECTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -566,6 +566,7 @@
* [NextSmallerElement](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/NextSmallerElement.java)
* [PostfixToInfix](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/PostfixToInfix.java)
* [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)
* strings
* [AhoCorasick](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/strings/AhoCorasick.java)
Expand Down Expand Up @@ -1027,6 +1028,7 @@
* [NextSmallerElementTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/stacks/NextSmallerElementTest.java)
* [PostfixToInfixTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/stacks/PostfixToInfixTest.java)
* [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)
* strings
* [AhoCorasickTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/strings/AhoCorasickTest.java)
Expand Down
60 changes: 60 additions & 0 deletions src/main/java/com/thealgorithms/stacks/SortStack.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package com.thealgorithms.stacks;

import java.util.Stack;

/**
* A utility class that provides a method to sort a stack using recursion.
* The elements are sorted in ascending order, with the largest element at the top.
* This algorithm is implemented using only recursion and the original stack,
* without utilizing any additional data structures apart from the stack itself.
*/
public final class SortStack {
private SortStack() {
}

/**
* Sorts the given stack in ascending order using recursion.
* The sorting is performed such that the largest element ends up on top of the stack.
* This method modifies the original stack and does not return a new stack.
*
* The algorithm works as follows:
* 1. Remove the top element.
* 2. Recursively sort the remaining stack.
* 3. Insert the removed element back into the sorted stack at the correct position.
*
* @param stack The stack to be sorted, containing Integer elements.
* @throws IllegalArgumentException if the stack contains `null` elements.
*/
public static void sortStack(Stack<Integer> stack) {
if (stack.isEmpty()) {
return;
}

int top = stack.pop();
sortStack(stack);
insertInSortedOrder(stack, top);
}

/**
* Helper method to insert an element into the correct position in a sorted stack.
* This method is called recursively to place the given element into the stack
* such that the stack remains sorted in ascending order.
*
* The element is inserted in such a way that all elements below it are smaller
* (if the stack is non-empty), and elements above it are larger, maintaining
* the ascending order.
*
* @param stack The stack in which the element needs to be inserted.
* @param element The element to be inserted into the stack in sorted order.
*/
private static void insertInSortedOrder(Stack<Integer> stack, int element) {
if (stack.isEmpty() || element > stack.peek()) {
stack.push(element);
return;
}

int top = stack.pop();
insertInSortedOrder(stack, element);
stack.push(top);
}
}
77 changes: 77 additions & 0 deletions src/test/java/com/thealgorithms/stacks/SortStackTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package com.thealgorithms.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.BeforeEach;
import org.junit.jupiter.api.Test;

public class SortStackTest {

private Stack<Integer> stack;

@BeforeEach
public void setUp() {
stack = new Stack<>();
}

@Test
public void testSortEmptyStack() {
SortStack.sortStack(stack);
assertTrue(stack.isEmpty()); // An empty stack should remain empty
}

@Test
public void testSortSingleElementStack() {
stack.push(10);
SortStack.sortStack(stack);
assertEquals(1, stack.size());
assertEquals(10, (int) stack.peek()); // Single element should remain unchanged
}

@Test
public void testSortAlreadySortedStack() {
stack.push(1);
stack.push(2);
stack.push(3);
stack.push(4);
SortStack.sortStack(stack);

assertEquals(4, stack.size());
assertEquals(4, (int) stack.pop());
assertEquals(3, (int) stack.pop());
assertEquals(2, (int) stack.pop());
assertEquals(1, (int) stack.pop());
}

@Test
public void testSortUnsortedStack() {
stack.push(3);
stack.push(1);
stack.push(4);
stack.push(2);
SortStack.sortStack(stack);

assertEquals(4, stack.size());
assertEquals(4, (int) stack.pop());
assertEquals(3, (int) stack.pop());
assertEquals(2, (int) stack.pop());
assertEquals(1, (int) stack.pop());
}

@Test
public void testSortWithDuplicateElements() {
stack.push(3);
stack.push(1);
stack.push(3);
stack.push(2);
SortStack.sortStack(stack);

assertEquals(4, stack.size());
assertEquals(3, (int) stack.pop());
assertEquals(3, (int) stack.pop());
assertEquals(2, (int) stack.pop());
assertEquals(1, (int) stack.pop());
}
}
Loading