As the challenge mentions "recursive", it looks like you should use the call stack (and stack frames) for preserving data while sorting takes place.
I would suggest a selection-sort kind of algorithm, where the stack has an unsorted, upper part and a sorted lower part. At the start, the unsorted part is the whole stack. Then make n iterations and in each iteration we find the greatest value in the unsorted part and move it to the top of the sorted part.
In more detail, in each iteration we perform the following steps:
Recursively pop values, and keep track of the greatest value encountered. Remember at each recursive call whether the current value was found to be greater than the greatest value found so far.
At the bottom of the unsorted part, push that greatest value and stop the recursion. This makes the stack size 1 greater upon exit of the function than it was on entry.
While exiting the recursive calls, if the current value was the one passed down the recursion as the greatest so far, then check if the stack is still greater than expected:
- If so, this means that indeed that value turned out to be the all-over maximum, and it should not be pushed unto the stack again, as it was put at the bottom. By not pushing it again, the stack size is now equal upon exit as it was on entry.
- If not so, this means that a greater value was identified deeper in the recursion tree, and the current value should just be pushed to the stack again.
If the current value was not the one passed down the recursion as the greatest so far, just push back the value.
After this phase we have moved the greatest value to the bottom of the stack. Now define the "bottom" of the stack as being one entry higher, so to leave the found least value untouched. Repeat the above steps until that new "bottom" is reached.
Keep raising the bottom like that until that bottom matches the top of the stack. This indicates that the stack is completely sorted.
Here is an implementation in JavaScript:
function moveMaxDown(stack, bottom, maxValue) {
let value = stack.pop();
let len = stack.length; // Memorize length before recursing
if (len > bottom) { // Not reached the bottom yet
if (value <= maxValue) {
moveMaxDown(stack, bottom, maxValue);
} else {
moveMaxDown(stack, bottom, value);
if (stack.length > len) return; // Current value was already inserted
}
} else {
if (value <= maxValue) stack.push(maxValue); // Extra push
}
stack.push(value);
}
function stackSort(stack) {
for (let bottom = 0; bottom < stack.length; bottom++) {
moveMaxDown(stack, bottom, -Infinity);
}
return stack;
}
// demo
console.log(stackSort([3, 2, 1]));
console.log(stackSort([11, 2, 32, 3, 41]));