Skip to content

Instantly share code, notes, and snippets.

@KeshariPiyush24
Created September 29, 2024 18:40
Show Gist options
  • Save KeshariPiyush24/03b697ecba916457d7e000a8fbebd14e to your computer and use it in GitHub Desktop.
Save KeshariPiyush24/03b697ecba916457d7e000a8fbebd14e to your computer and use it in GitHub Desktop.
Sort Stack using Recursion

Sorting a Stack using Recursion

Intuition

The core idea behind sorting a stack using recursion is to:

  1. Remove elements from the stack one by one.
  2. Recursively sort the remaining stack.
  3. Insert the removed element at the correct position in the sorted stack.

This approach uses the call stack to temporarily hold elements while sorting them, allowing for an in-place sort without additional data structures.

Algorithm

The algorithm uses two main recursive functions:

  1. sort: Sorts the entire stack.
  2. insertAtRightPosition: Inserts an element at the correct position in a sorted stack.

sort

  • Base case: If the stack is empty or has only one element, it's already sorted.
  • Recursive case:
    1. Remove the top element.
    2. Sort the remaining stack.
    3. Insert the removed element at the correct position in the sorted stack.

insertAtRightPosition

  • Base case 1: If the stack is empty, push the item.
  • Base case 2: If the top element is smaller than the item to insert, push the item.
  • Recursive case:
    1. Remove the top element.
    2. Recursively insert the item at the correct position.
    3. Push back the removed top element.

Time Complexity

  • O(n^2), where n is the number of elements in the stack.
  • For each element (n times), we potentially need to remove and reinsert all elements below it (up to n times).

Space Complexity

  • O(n), where n is the number of elements in the stack.
  • The maximum depth of the recursive call stack is n.

Java Implementation

class GfG {
    public Stack<Integer> sort(Stack<Integer> stack) {
        // Base case: if the stack is empty or has only one element, it's already sorted
        if (stack.isEmpty() || stack.size() == 1) {
            return stack;
        }
        
        // Remove the top element
        int top = stack.pop();
        
        // Recursively sort the remaining stack
        sort(stack);
        
        // Insert the top element at the correct position of the sorted stack
        insertAtRightPosition(stack, top);
        
        return stack;
    }
    
    private static void insertAtRightPosition(Stack<Integer> stack, int item) {
        // Base case 1: if the stack is empty, push the item
        if (stack.isEmpty()) {
            stack.push(item);
            return;
        }
        
        // Base case 2: if the top element is smaller than item, push the item
        if (stack.peek() < item) {
            stack.push(item);
            return;
        }
        
        // Remove the top element
        int top = stack.pop();
        
        // Recursively insert the item at the right position
        insertAtRightPosition(stack, item);
        
        // Push back the top element
        stack.push(top);
    }
}

Detailed Analysis

  1. The sort function is called recursively for each element in the stack, giving us n recursive calls.

  2. For each of these calls, we also call insertAtRightPosition. In the worst case (when the stack is in reverse order), insertAtRightPosition might need to remove and reinsert all elements below the current element.

  3. This leads to a series of operations: n + (n-1) + (n-2) + ... + 2 + 1, which sums up to n(n+1)/2.

  4. Therefore, the time complexity is O(n^2).

  5. The space complexity is O(n) due to the recursive call stack, which in the worst case will be as deep as the number of elements in the stack.

Trade-offs and Considerations

  • This recursive solution, while elegant, is not the most efficient approach for sorting a stack.
  • An iterative solution using an additional stack or converting to an array, sorting, and converting back to a stack could potentially be more efficient.
  • The recursive approach is valuable for understanding recursion and stack operations, but may not be suitable for large stacks due to the risk of stack overflow and quadratic time complexity.

Conclusion

The recursive stack sorting algorithm demonstrates a clever use of the call stack to sort elements in-place. However, for practical applications, especially with large datasets, more efficient sorting algorithms should be considered.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment