Reversing a linked list in python

前端 未结 11 2351
失恋的感觉
失恋的感觉 2020-12-08 12:28

I am asked to reverse a which takes head as parameter where as head is a linked list e.g.: 1 -> 2 -> 3 which was returned from a function already defined I tried to implemen

相关标签:
11条回答
  • 2020-12-08 12:52

    Here is the whole thing in one sheet. Contains the creation of a linked list, and code to reverse it.

    Includes an example so you can just copy and paste into an idle .py file and run it.

    class Node(object):
        def __init__(self, value, next=None): 
            self.value = value                
            self.next = next                  
    
    
    def reverse(head):
        temp = head
        llSize = 0
        while temp is not None:
            llSize += 1
            temp = temp.next
        for i in xrange(llSize-1,0,-1):
            xcount = 0
            temp = head
            while (xcount != i):
                temp.value, temp.next.value = temp.next.value, temp.value
                temp = temp.next
                xcount += 1
        return head
    
    
    def printnodes(n):
        b = True
        while b == True:
            try:
                print n.value
                n = n.next
            except:
                b = False
    
    n0 = Node(1,Node(2,Node(3,Node(4,Node(5,)))))
    print 'Nodes in order...'
    printnodes(n0)
    print '---'
    print 'Nodes reversed...'
    n1 = reverse(n0)
    printnodes(n1)
    
    0 讨论(0)
  • 2020-12-08 12:55

    Node class part borrowed from interactive python.org: http://interactivepython.org/runestone/static/pythonds/BasicDS/ImplementinganUnorderedListLinkedLists.html

    I created the reversed function. All comments in the loop of reverse meant for 1st time looping. Then it continues.

    class Node():
      def __init__(self,initdata):
        self.d = initdata
        self.next = None
    
      def setData(self,newdata):
        self.d = newdata
    
      def setNext(self,newnext):
        self.next = newnext
    
      def getData(self):
        return self.d
    
      def getNext(self):
        return self.next
    
    class LinkList():
      def __init__(self):
        self.head = None
    
      def reverse(self):
        current = self.head   >>> set current to head(start of node)
        previous = None       >>>  no node at previous
        while current !=None: >>> While current node is not null, loop
            nextt =  current.getNext()  >>> create a pointing var to next node(will use later)
            current.setNext(previous)   >>> current node(or head node for first time loop) is set to previous(ie NULL), now we are breaking the link of the first node to second node, this is where nextt helps(coz we have pointer to next node for looping)
            previous = current  >>> just move previous(which was pointing to NULL to current node)
            current = nextt     >>> just move current(which was pointing to head to next node)
    
        self.head = previous   >>> after looping is done, (move the head to not current coz current has moved to next), move the head to previous which is the last node.
    
    0 讨论(0)
  • 2020-12-08 13:02

    Following is the generalized code to reverse a singly linked list, where head is given as function's argument:

    def reverseSll(ll_head):
        # if head of the linked list is empty then nothing to reverse
        if not ll_head:
            return False
        # if only one node, reverse of one node list is the same node
        if not ll_head.next:
            return ll_head
        else:
            second = ll_head.next # get the second node of the list
            ll_head.next = None # detach head node from the rest of the list
            reversedLL = reverseSll(second) # reverse rest of the list
            second.next = ll_head # attach head node to last of the reversed list
            return reversedLL
    

    Let me explain what I am doing here:

    1) if head is null or head.next is null(only one node left in the list) return node
    2) else part: take out 1st node, remove its link to rest of the list, reverse rest of the list(reverseSll(second)) and add 1st node again at last and return the list

    Github link for the same

    0 讨论(0)
  • 2020-12-08 13:04

    Most previous answers are correct but none of them had the complete code including the insert method before and and after the reverse so you could actually see the outputs and compare. That's why I'm responding to this question. The main part of the code of course is the reverse_list() method. This is in Python 3.7 by the way.

    class Node(object):
        def __incurrent__(self, data=None, next=None):
            self.data = data
            self.next = next
    
    
    class LinkedList(object):
    
        def __incurrent__(self, head=None):
            self.head = head
    
        def insert(self, data):
            tmp = self.head
            self.head = Node(data)
            self.head.next = tmp
    
        def reverse_list(self):
            current = self.head
            prev = None
    
            while current :
                #create tmp to point to next
                tmp = current.next
                # set the next to point to previous
                current.next = prev
                # set the previous to point to current
                prev = current
                #set the current to point to tmp
                current = tmp
            self.head = prev
    
    
        def print(self):
            current = self.head
            while current != None:
                print(current.data,end="-")
                current = current.next
            print(" ")
    
    
    lk = LinkedList()
    lk.insert("a")
    lk.insert("b")
    lk.insert("c")
    
    lk.print()
    lk.reverse_list()
    lk.print()
    

    output:

    c-b-a- 
    a-b-c- 
    
    0 讨论(0)
  • 2020-12-08 13:07

    I found blckknght's answer useful and it's certainly correct, but I struggled to understand what was actually happening, due mainly to Python's syntax allowing two variables to be swapped on one line. I also found the variable names a little confusing.

    In this example I use previous, current, tmp.

    def reverse(head):
        current = head
        previous = None
    
        while current:
            tmp = current.next
            current.next = previous   # None, first time round.
            previous = current        # Used in the next iteration.
            current = tmp             # Move to next node.
    
        head = previous
    

    Taking a singly linked list with 3 nodes (head = n1, tail = n3) as an example.

    n1 -> n2 -> n3

    Before entering the while loop for the first time, previous is initialized to None because there is no node before the head (n1).

    I found it useful to imagine the variables previous, current, tmp 'moving along' the linked list, always in that order.

    First iteration

    previous = None

    [n1] -> [n2] -> [n3] current tmp current.next = previous

    Second iteration

    [n1] -> [n2] -> [n3] previous current tmp current.next = previous

    Third iteration

    # next is None
    

    [n1] -> [n2] -> [n3] previous current current.next = previous

    Since the while loop exits when current == None the new head of the list must be set to previous which is the last node we visited.

    Edited

    Adding a full working example in Python (with comments and useful str representations). I'm using tmp rather than next because next is a keyword. However I happen to think it's a better name and makes the algorithm clearer.

    class Node:
        def __init__(self, value):
            self.value = value
            self.next = None
    
        def __str__(self):
            return str(self.value)
    
        def set_next(self, value):
            self.next = Node(value)
            return self.next
    
    
    class LinkedList:
        def __init__(self, head=None):
            self.head = head
    
        def __str__(self):
            values = []
            current = self.head
            while current:
                values.append(str(current))
                current = current.next
    
            return ' -> '.join(values)
    
        def reverse(self):
            previous = None
            current = self.head
    
            while current.next:
                # Remember `next`, we'll need it later.
                tmp = current.next
                # Reverse the direction of two items.
                current.next = previous
                # Move along the list.
                previous = current
                current = tmp
    
            # The loop exited ahead of the last item because it has no
            # `next` node. Fix that here.
            current.next = previous
    
            # Don't forget to update the `LinkedList`.
            self.head = current
    
    
    if __name__ == "__main__":
    
        head = Node('a')
        head.set_next('b').set_next('c').set_next('d').set_next('e')
    
        ll = LinkedList(head)
        print(ll)
        ll.revevse()
        print(ll)
    

    Results

    a -> b -> c -> d -> e
    e -> d -> c -> b -> a
    
    0 讨论(0)
  • 2020-12-08 13:08

    I tried a different approach, in place reversal of the LList. Given a list 1,2,3,4

    If you successively swap nearby nodes,you'll get the solution.

    len=3 (size-1)
    2,1,3,4
    2,3,1,4
    2,3,4,1
    
    len=2 (size-2)
    3,2,4,1
    3,4,2,1
    
    len=1 (size-3)
    4,3,2,1
    

    The code below does just that. Outer for loop successively reduces the len of list to swap between. While loop swaps the data elements of the Nodes.

    def Reverse(head):
        temp = head
        llSize = 0
        while temp is not None:
            llSize += 1
            temp = temp.next
    
    
        for i in xrange(llSize-1,0,-1):
            xcount = 0
            temp = head
            while (xcount != i):
                temp.data, temp.next.data = temp.next.data, temp.data
                temp = temp.next
                xcount += 1
        return head
    

    This might not be as efficient as other solutions, but helps to see the problem in a different light. Hope you find this useful.

    0 讨论(0)
提交回复
热议问题