user908015
user908015

Reputation:

Reversing a Stack in Python using recursion

I'm doing some practise questions. This one needs to reverse a stack without using any other data structures except another stack.

I know I will need a helper function that appends the pop-ed numbers once the original stack is empty.

Can somebody get me started? I'm stuck here

def flip_stack(s):
    if not s.is_empty():
        temp = s.pop
        flip_stack(s)

Thanks!

The Stack class has pop, push and is_empty functions.

Upvotes: 5

Views: 3133

Answers (6)

mtadd
mtadd

Reputation: 2555

class Stack(object):
    def __init__(self,items=[]):
        self.stack = items

    def is_empty(self):
        return not self.stack

    def pop(self):
        return self.stack.pop()

    def push(self,val):
        self.stack.append(val)

    def __repr__(self):
        return "Stack {0}".format(self.stack)

def flip_stack(stack):
    def flip_stack_recursive(stack,new_stack=Stack()):
        if not stack.is_empty():
            new_stack.push(stack.pop())
            flip_stack_recursive(stack,new_stack)
        return new_stack
    return flip_stack_recursive(stack)


s = Stack(range(5))
print s
print flip_stack(s)

yields

Stack [0, 1, 2, 3, 4]
Stack [4, 3, 2, 1, 0]

You could even get a little fancy using the fact that the closure keeps the stack parameter of flip_stack in the scope of the recursive function, so you don't need it to be a parameter to the inner function. e.g.

def flip_stack(stack):
    def flip_stack_recursive(new_stack):
        if not stack.is_empty():
            new_stack.push(stack.pop())
            flip_stack_recursive(new_stack)
        return new_stack
    return flip_stack_recursive(Stack())

Or, get rid of all parameters on the recursive function, and your thread stack frame will thank you:

def flip_stack(stack):
    new_stack = Stack()
    def flip_stack_recursive():
        if not stack.is_empty():
            new_stack.push(stack.pop())
            flip_stack_recursive()
    flip_stack_recursive()
    return new_stack

Upvotes: 0

Óscar López
Óscar López

Reputation: 235984

Here's another possibility, using an accumulator and a helper function. I'm only using the methods provided in your Stack class, and no other data structures (such as Python's lists) :

def flip_stack(s):
    return flip_stack_helper(s, Stack()) # Stack is your stack class

def flip_stack_helper(s, t):
    if s.is_empty():
        return t
    t.push(s.pop())
    return flip_stack_helper(s, t)

Be aware that the original stack will be empty at the end, and the flipped stack is returned.

Upvotes: 0

Abhijit
Abhijit

Reputation: 63707

Assuming no data structure should be used even not list to hold the final result here is one possible solution

The Stack here would be considered a list which supports the following function

append(elem)   ---- push(elem) 
pop()          ---- pop() 
if <some stack>---- NotEmpty()

Solution 1:

def flip_stack(s):
    while True:
        if s:
            yield s.pop()
        else:
            return

stack = [1,2,3,4,5]
revStack = [x for x in flip_stack(stack)]

Even you can code without using the IsEmpty ot NotEmpty functionality

Solution 2:

def flip_stack(s):
    while True:
        try:
            yield s.pop()
        except IndexError:
            return

Note ** Using Exception for Conditional Checking is an accepted behavior in Python as it has no added overhead as in C++

Upvotes: 0

fraxel
fraxel

Reputation: 35269

def reverse(orig, reversel=None):
    if not reversel:
        reversel = []
    reversel.append(orig.pop())
    if orig:
        reverse(orig, reversel)
    return reversel

stack = [1, 2, 3, 4, 5]
stack = reverse(stack)
print stack
[5, 4, 3, 2, 1]

Upvotes: 1

Fred
Fred

Reputation: 1021

>>> liste = [1, 2, 3, 4, 5]
>>> liste[::-1]
[5, 4, 3, 2, 1]

Upvotes: 0

grifaton
grifaton

Reputation: 4046

The following works if stack is a native Python list:

def flip(stack):
    def helper(old_stack, new_stack):
        if old_stack:
            new_stack.append(old_stack.pop())
            return helper(old_stack, new_stack)
        else:
            return new_stack
    return helper(stack[:], [])

stack[:] causes the original stack to be preserved.

It shouldn't be hard to modify this to handle your given Stack class.

Upvotes: 0

Related Questions