Sorting an array entirely using recursion is an excellent exercise in understanding recursive leaps of faith. The core idea is to reduce the problem size: to sort an array of size N, we can recursively sort the array of size N-1. Once the N-1 elements are sorted, our task reduces to inserting the Nth element into its correct position within the already sorted N-1 elements.
This requires two recursive functions:
sortArray(): Reduces the array size by removing the last element, recursively calls itself to sort the remaining array, and then callsinsert().insert(): Takes a sorted array and an element. If the array is empty or the last element is smaller than or equal to the element to insert, we simply append it. Otherwise, we remove the last element, recursively callinsert(), and then put the removed element back.
// Pseudocode for Sort:
// If array is size 1 or empty, return.
// Pop the last element `temp`.
// Recursively call sortArray(array).
// Call insert(array, temp).
// Pseudocode for Insert:
// If array is empty or last element <= temp, append `temp` and return.
// Pop the last element `val`.
// Recursively call insert(array, temp).
// Append `val` back.
#include <vector>
using namespace std;
class Solution {
public:
void insert(vector<int>& arr, int temp) {
// Base case: if array is empty or the last element is smaller/equal
if (arr.empty() || arr.back() <= temp) {
arr.push_back(temp);
return;
}
// Hypothesis: remove the larger element
int val = arr.back();
arr.pop_back();
// Induction: insert the temp in the remaining sorted array
insert(arr, temp);
// Re-add the removed element
arr.push_back(val);
}
void sortArray(vector<int>& arr) {
// Base case
if (arr.size() <= 1) {
return;
}
// Hypothesis: remove last element
int temp = arr.back();
arr.pop_back();
// Recursively sort the remaining array
sortArray(arr);
// Induction: insert the element in the sorted array
insert(arr, temp);
}
};- Time Complexity: . The
sortArrayfunction is called times. For each call,insertis called. In the worst case (e.g., array sorted in reverse order),insertremoves all elements one by one, taking time per call. Thus, . - Space Complexity: auxiliary space. This is due to the recursion stack.
sortArrayuses stack frames, andinsertcan also use up to stack frames at each step.
- Empty Array: The base case
arr.size() <= 1correctly handles an empty array by returning immediately. - Already Sorted Array: The
insertfunction will hit its base casearr.back() <= tempimmediately, making it for insertion, butsortArraystill does calls. Total time becomes . - Reverse Sorted Array: This triggers the worst-case time complexity .
- Duplicate Elements:
arr.back() <= temphandles duplicates gracefully, maintaining a stable relative order.
- Thought Process & Recognition: This pattern is explicitly about Base Condition, Hypothesis, and Induction (BHI).
- Hypothesis: Assume
sortArrayup to the second-to-last element works perfectly. - Induction Step: How do we make the whole array sorted if the remaining elements are sorted? We just insert the last element in its correct place.
- Hypothesis: Assume
- Mental Model: Imagine holding a deck of cards. You take the top card off and ask a friend to magically sort the rest of the deck. When they hand it back sorted, you figure out where to insert your single card. But since you can only access the cards one by one from the top, you pull cards off the sorted deck until you find the right spot, put your card in, and then put the pulled cards back.