Reversing a linked list in python

前端 未结 11 2353
失恋的感觉
失恋的感觉 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 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
    

提交回复
热议问题