0

I am doing a Python program that implements linked list to support a few functions, one of the functions I need to do is to reverse a stack. I have made a Node, LinkedList and Stack classes, here is my Code so far:

class ListNode:

    def __init__(self, Object):
        self.Object = Object
        self.next = None

class LinkedList:

    def __init__(self):
        self.head = None # first node
        self.tail = None # last node

    def addLast(self, Object):
        newNode = ListNode(Object)
        if self.head == None:
            self.head = newNode
            self.tail = newNode
        else:
           self.tail.next = newNode
           self.tail = newNode

    def removeFirst(self):
        if self.head == None:
            return

        self.head = self.head.next
        if self.head == None:
            self.tail = None

    def removeLast(self, Object):
        if self.head == None:
            return

        current = self.head
        prev = None
        while current.next != None:
            prev = current
            current = current.next

        if prev == None:
            self.head = None
            self.tail = None
        else:
            prev.next = None
            self.tail = prev

    def get(self, index):
        current = self.head
        i = 0
        while i < index and current != None:
            current = current.next
            i = i + 1
        if current != None and index >= 0:
            return current.Object
        else:
            return None

    def size(self):
        current = self.head
        count = 0
        while current != None:
            count = count + 1
            current = current.next
        return count

    def isEmpty(self):
        return self.head == None

    def printList(self):
        if self.head != None:
            current = self.head
            while current != None:
                print(current.Object, end = ' ')
                current = current.next
        print()

# -------------------- STACK ---------------------------------------------------
class Stack:
    # constructor implementation
    def __init__(self):
        self.llist = LinkedList()

    def front(self):
        return self.llist.get(0)

    def dequeue(self):
        self.llist.removeFirst()

    def queue(self, Object):
        self.llist(Object)

    def push(self, Object):
        self.llist.addLast(Object)

    def pop(self, Object):
        self.llist.removeLast(Object)

    def printStack(self):
        self.llist.printList()

    def size(self):
        return self.llist.size()

    def isEmpty(self):
        return self.llist.isEmpty()

# ----------------------- Reverse LIST ------------------------------
def Reverse(S):
    # S is a Stack Object

Here is my attempt at the problem:

def rRecursive( self ) :
    self._rRecursive( self.head )

def _reverseRecursive( self, n ) :
    if None != n:
      right = n.next
      if self.head != n:
        n.next = self.head
        self.head = n
      else:
        n.next = None

      self._rRecursive( right )

def Reverse(S):
    s.rRecursive()

If this was an ordinary list I could easily reverse it using [::-1] but I cannot since the linkedlist is an object. I was thinking maybe I could use temporary values so I can someone append the beginning of the stack to a list and then somehow convert it back into a stack object.

Edit for duplication: The goal of my program is use an existing Stack and reverse it. The linked post deals with a linked list that was already in a list format.

def get(self, index):
        current = self.head
        i = 0
        while i < index and current != None:
            current = current.next
            i = i + 1
        if current != None and index >= 0:
            return current.Object
        else:
            return None

Edit 2: added my get function.

class Stack:
    # constructor implementation
    def __init__(self):
        self.llist = LinkedList()

    def front(self):
        return self.llist.get(0)

        # push method implementation
    def push(self, Object):
        self.llist.addLast(Object)

    def pop1(self):
        self.llist.removeLast1()

def Reverse(S): 
    new_stack = Stack()
    while not S.isEmpty():
        new_stack.push(S.front())
        S.pop1()
    return new_stack

# Current Stack after Push: 12 14 40 13
# Stack after Pop: 12 14 40
# Stack after Reversal: 12 12 12

Edit 3: Added a rework of my code, it returns back a wrong reversal with the first element over and over again.

Yozuru
  • 123
  • 1
  • 4
  • 14
  • Possible duplicate of [Reversing a linked list in python](http://stackoverflow.com/questions/21529359/reversing-a-linked-list-in-python) – Shawn Mehan Oct 21 '15 at 00:41
  • 1
    You could reverse it with `[::1]` if you implemented `__getitem__` and have it accept `val` as a [`slice`](https://docs.python.org/library/functions.html#slice). I guess this is your homework assignment? – metatoaster Oct 21 '15 at 00:44
  • Yup this is my homework assignment, this is the last function that I need to do. I have edited into the problem my get item function I was working earlier. The problem I was running into was that I couldn't reverse my Stack because it was already a Stack object. – Yozuru Oct 21 '15 at 00:54

5 Answers5

2

It's quite easy to reverse a stack using basic stack operations. Pop each item off the old stack and push it onto a new one.

def reverse(stack):
    new_stack = Stack()
    while not stack.isEmpty():
        new_stack.push(stack.front())
        stack.pop()
    return new_stack

You could do something similar to destructively reverse the LinkedList within the Stack while reusing the stack object itself, you'd just need to use the list operations rather than the stack operations that are aliased to them.

Speaking of stack operations, you'll probably find that your stack performs better if you push and pop from the front, rather than the back. Removing an item from the end of the linked list requires iterating over the whole list (to find the next-to-last node). In contrast, both adding and removing from the front are fast.

Blckknght
  • 100,903
  • 11
  • 120
  • 169
  • Hello Blck, thanks for taking time to answer my question. I have tried your method and it works to an extent, however, I am not getting a reversal of the Stack, but rather just the first element of the element list repeating over. Here is what I have as an output: Stack after Pop: 12 14 40 Stack after Reversal: 12 12 12 I have also updated my post again to show what I have for each of the blocks in the code snippet. – Yozuru Oct 21 '15 at 02:46
  • 1
    Oh, it looks like your stack is buggy. You're pushing and popping from the end, but the only value you give access to is the front one. As I suggested in the question, you should probably change `push` and `pop` to work from the front, which will make the logic work without modifying `front` (though changing that would be an alternative fix). – Blckknght Oct 21 '15 at 06:43
  • Thanks for getting back to me Blck, I'll rework my code so that my push and pop would be working from the front! – Yozuru Oct 22 '15 at 01:22
1

You shouldn't have to fiddle with link pointers in your reversal function. I assume that you have a pop() method and other basics with your stack; if not, then clone your removeFirst function to return the removed node.

Now, the recursive function is simple: pop the head of the list, reverse the remaining stack (if any), and add the popped node to the end. Does this handle your problem?

def reverseStack(self):
    move_me = self.pop()
    if not self.isEmpty():
        return (self.reverseStack()).addLast(move_me)
    else:
        new_stack = Stack()
        return new_stack.addLast(move_me)
Prune
  • 76,765
  • 14
  • 60
  • 81
  • I have tried your method but I ran into the error with reverseStack() not being defined in the 1st return unfortunately. – Yozuru Oct 21 '15 at 03:28
  • This is not finished code to paste in place; you need to adapt and place it properly. If it's not defined, I suspect that you didn't make it a class method. – Prune Oct 21 '15 at 03:38
  • You're absolutely correct, apologies for making you reply to my mistake. I'll rework again on my own using your logic and put it into my class method for stacks. Thanks for the help. – Yozuru Oct 22 '15 at 01:26
1

Other approaches to solving this problem: Cheat.

Define a __iter__ method (which makes sense in any event; iteration is a core Python behavior) to make your type iterable. Simple example:

def __iter__(self):
    cur = self.head
    while cur is not None:
        yield cur.Object
        cur = cur.next

Then just do:

values = list(self)  # Creates a list containing the current set of values
self.head = self.tail = None  # Clear existing linked list
# Add back all the values in reverse order
for value in reversed(values):
    self.addLast(value)

Sure, it's likely less efficient in memory allocation/deallocation overhead than doing it properly. But the effect is likely marginal, and it simplifies the implementation code dramatically.

Of course, doing it properly isn't that hard, it's just slightly more confusing (totally untested, but it should be close to right):

def reverse(self):
    # Start at beginning, which will be new end
    cur, last = self.head, None
    # Reverse head and tail pointers in advance
    self.head, self.tail = self.tail, self.head
    # Traverse while reversing direction of each node pointer
    while cur is not None:
        # Tuple pack and unpack allows one-line variable swap
        cur.next, cur, last = last, cur.next, cur
ShadowRanger
  • 143,180
  • 12
  • 188
  • 271
0

The usual algorithm for reversing things using basic data structures is to use the fact that a stack is a first in last out data structure. That means if you pop until the stack is empty, you will get the items in the opposite order you pushed them on.

But it looks like you want to do this via recursive functions rather than an explicit stack - in this case, your function would normally fetch the front element,then recurse on the rest of the data structure, then handle that first element. This gets all the elements off in order, but handles them in the opposite order as each recursive call finishes and you work your way back up the call stack. If you neex to add the elements to a reversed data structure (and not just print them), you can build it up via return values by noticing that once you have the reverse if everything after the current element, you just need to attach that element to the front and you have the reverse of everything you were handed.

lvc
  • 34,233
  • 10
  • 73
  • 98
0
class Node(object):
    def __init__(self, data=None, next_node=None):
       self.data = data
       self.next = next_node


def Reverse(head):
    if head == None :
        return None
    elif head.next == None :
        return head            # returns last element from stack
    else :
        temp = head.next       # stores next element while moving forward  
        head.next = None       # removes the forward link
        li = Reverse(temp)     # returns the last element
        temp.next = head       # now do the reverse link here
        return li

def main() :
    temp4 = Node(4,None)
    temp3 = Node(3,temp4)
    temp2 = Node(2,temp3)
    head = Node(1,temp2)
    res = Reverse(head)
    while res != None :
        print(res.data)
        res = res.next
main()
  • Your answer could be far more helpful if it included comments or more of a description about how your answer solves the question. – Whit Waldo Feb 14 '17 at 01:42
  • the code puts the list in a stack recursively, then from the last element, you start linking backwards. Thats y i use the return head, to return the last element from the stack and use it as head. the temp variable is used to store the next element in the list, this is used bcoz we have to remove the forward links and we need the next element to put in the stack. – Pragash Vijayaragavan Feb 22 '17 at 21:11